将原问题转化为求完全由1组成的最大子矩阵。
挺经典的通过dp将n^3转化为n^2。
1 /* 4328 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int maxn = 1005; 44 char s[maxn][maxn]; 45 int a[maxn][maxn]; 46 int L[maxn][maxn], R[maxn][maxn], T[maxn][maxn]; 47 int n, m; 48 49 int calc() { 50 int ret = 0; 51 52 rep(j, 0, m+1) { 53 T[0][j] = 0; 54 L[0][j] = 1; 55 R[0][j] = m; 56 } 57 58 rep(i, 1, n+1) { 59 int l; 60 l = 0; 61 rep(j, 1, m+1) { 62 if (a[i][j] == 1) { 63 T[i][j] = T[i-1][j] + 1; 64 L[i][j] = max(L[i-1][j], l+1); 65 } else { 66 T[i][j] = 0; 67 L[i][j] = 1; 68 l = j; 69 } 70 } 71 72 int r; 73 r = m + 1; 74 per(j, 1, m+1) { 75 if (a[i][j] == 1) { 76 R[i][j] = min(R[i-1][j], r-1); 77 } else { 78 R[i][j] = m; 79 r = j; 80 } 81 } 82 83 rep(j, 1, m+1) { 84 if (a[i][j]) { 85 int h = T[i][j]; 86 int w = R[i][j] - L[i][j] + 1; 87 ret = max(ret, w+h); 88 } 89 } 90 } 91 92 return ret << 1; 93 } 94 95 void solve() { 96 int ans = 0, tmp; 97 98 // blue 99 rep(i, 1, n+1) 100 rep(j, 1, m+1) 101 a[i][j] = s[i][j] == 'B'; 102 tmp = calc(); 103 ans = max(ans, tmp); 104 105 // red 106 rep(i, 1, n+1) 107 rep(j, 1, m+1) 108 a[i][j] = s[i][j] == 'R'; 109 tmp = calc(); 110 ans = max(ans, tmp); 111 112 rep(i, 1, n+1) { 113 rep(j, 1, m+1) { 114 if ((i+j) & 1) { 115 a[i][j] = s[i][j]!='R'; 116 } else { 117 a[i][j] = s[i][j]=='R'; 118 } 119 } 120 } 121 tmp = calc(); 122 ans = max(ans, tmp); 123 124 rep(i, 1, n+1) { 125 rep(j, 1, m+1) { 126 if ((i+j) & 1) { 127 a[i][j] = s[i][j]=='R'; 128 } else { 129 a[i][j] = s[i][j]!='R'; 130 } 131 } 132 } 133 tmp = calc(); 134 ans = max(ans, tmp); 135 136 printf("%d ", ans); 137 } 138 139 int main() { 140 ios::sync_with_stdio(false); 141 #ifndef ONLINE_JUDGE 142 freopen("data.in", "r", stdin); 143 freopen("data.out", "w", stdout); 144 #endif 145 146 int t; 147 148 scanf("%d", &t); 149 rep(tt, 1, t+1) { 150 scanf("%d %d", &n, &m); 151 rep(i, 1, n+1) 152 scanf("%s", s[i]+1); 153 printf("Case #%d: ", tt); 154 solve(); 155 } 156 157 #ifndef ONLINE_JUDGE 158 printf("time = %d. ", (int)clock()); 159 #endif 160 161 return 0; 162 }
数据生成器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**18 11 op = "RB" 12 fout.write("%d " % (t)) 13 for tt in xrange(t): 14 n = randint(100, 1000) 15 m = randint(100, 1000) 16 fout.write("%d %d " % (n, m)) 17 for i in xrange(n): 18 line = "" 19 for j in xrange(m): 20 idx = randint(0, 1) 21 line += op[idx] 22 fout.write("%s " % (line)) 23 24 25 def MovDataIn(): 26 desFileName = "F:eclipse_prjworkspacehdojdata.in" 27 shutil.copyfile("data.in", desFileName) 28 29 30 if __name__ == "__main__": 31 GenDataIn() 32 MovDataIn()