Portal

Portal

link

题意
Portal

题解

​ 首先要是一个大于等于五行四列,我们可以考虑枚举这个矩形的形状,也就是需要枚举上边U下边D左边L右边R,然后用一个二分的前缀和,来算出对应的权值。但是 5 ≤ n ≤ 400 , 4 ≤ m ≤ 400 5\le n\le400,4\le m\le400 5≤n≤400,4≤m≤400,这样是一个大约 O ( n 4 ) O(n^4) O(n4)的复杂度,必 T T T。考虑减少一维枚举,当我们确定了U,D,R的时候,他的L一定是接在前面出现的某一个合法的地方,因为至少是个四列的矩形,所以至少要包含当R往前三列的贡献,变的就是一个由 (U + 1, 1) ~ (U + 1, L) 的零 和 (D - 1, 1) ~ (D - 1, L)的零 和 (U + 1, L) ~ (D - 1, L) 这一列的0,再加上 (U + 1, 1) ~ (D - 1, L) 这个矩形的1,由于当前前缀和的右端点是确定的一个正数,那我们只需要动态的记录一下前面出现的可以接的L位置的权值的最大值,就是当前局面的最优解。维护所有局面的最优解就是res。

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <bitset>
#include <unordered_map>
#include <cmath> 
#include <stack>
#include <iomanip>
#include <deque> 
#include <sstream>
#define x first
#define y second
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 4e2 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
    e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
char a[N][N];
int sum[N][N], pos[N][N]; 
int res;
int get1(int x1, int y1, int x2, int y2) {
    return sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}
int get0(int x1, int y1, int x2, int y2) {
    return pos[x2][y2] - pos[x1 - 1][y2] - pos[x2][y1 - 1] + pos[x1 - 1][y1 - 1];
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    int T;
    cin >> T;
    while (T -- ) {
        cin >> n >> m;
        for (int i = 1; i <= n; i ++ ) cin >> a[i] + 1;
        res = INF;
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j  ++ ) {
                int val = a[i][j] - '0';
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + val; // 1的前缀和
                pos[i][j] = pos[i - 1][j] + pos[i][j - 1] - pos[i - 1][j - 1] + !val; // 0的前缀和
            } 
        for (int i = 1; i <= n - 4; i ++ ) 
            for (int j = i + 4; j <= n; j ++ ) {
                int tmp = n * m;
                for (int k = 4; k <= m; k ++ ) { 
                    tmp = min(tmp, 
get0(i + 1, k - 3, j - 1, k - 3) - get0(i, 1, i, k - 3) - get0(j, 1, j, k - 3) - get1(i + 1, 1, j - 1, k - 3) ); 
                    res = min(res, 
get1(i + 1, 1, j - 1, k - 1) + get0(i + 1, k, j - 1, k) + get0(i, 1, i, k - 1) + get0(j, 1, j, k - 1) + tmp);
                }
            }                
        cout << res << endl;
    }
    return 0;
}
上一篇:项目模块太多, 无法编译, java: java.lang.OutOfMemoryError: WrappedJavaFileObject[org.jetbrains.jps.javac.InputF


下一篇:Codeforces Round #745 (Div. 2) C. Portal 二维前缀和简单总结