bzoj1084: [SCOI2005]最大子矩阵
题很傻TAT
但是我的转移很蛋疼。。。
这么蛋疼的转移能一次写对还是佩服自己QAQ。。
记一下这蛋疼的代码(看到黄学长O(n·(a^m)·k)的没写对,貌似还有O(n^m*k)的写法。
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 7 using namespace std; 8 9 void setIO(const string& s) { 10 freopen((s + ".in").c_str(), "r", stdin); 11 freopen((s + ".out").c_str(), "w", stdout); 12 } 13 template<typename Q> Q read(Q& x) { 14 static char c, f; 15 for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1; 16 for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; 17 if(f) x = -x; 18 return x; 19 } 20 template<typename Q> Q read() { 21 static Q x; read(x); return x; 22 } 23 24 const int N = 100 + 10, INF = ~0u >> 1; 25 26 int n, m, f[N][5][11], K, a[N][2]; 27 28 template<typename Q> void maxit(Q& x, const Q& y) { 29 if(x < y) x = y; 30 } 31 32 int dp1() { 33 for(int i = 1; i <= n + 1; i++) { 34 for(int k = 0; k <= K; k++) { 35 maxit(f[i][1][k], f[i-1][1][k] + a[i][0]); 36 maxit(f[i][1][k], f[i-1][0][k] + a[i][0]); 37 maxit(f[i][0][k], f[i-1][0][k]); 38 if(k) maxit(f[i][0][k], f[i-1][1][k-1]); 39 } 40 } 41 return f[n+1][0][K]; 42 } 43 44 int dp2() { 45 for(int i = 1; i <= n + 1; i++) { 46 for(int k = 0; k <= K; k++) { 47 maxit(f[i][0][k], f[i-1][0][k]); 48 if(k) { 49 maxit(f[i][0][k], f[i-1][1][k-1]); 50 maxit(f[i][0][k], f[i-1][2][k-1]); 51 maxit(f[i][0][k], f[i-1][4][k-1]); 52 if(k >= 2) maxit(f[i][0][k], f[i-1][3][k-2]); 53 } 54 55 for(int j = 0; j < 2; j++) { 56 maxit(f[i][j+1][k], f[i-1][j+1][k] + a[i][j]); 57 maxit(f[i][j+1][k], f[i-1][0][k] + a[i][j]); 58 if(k) { 59 maxit(f[i][j+1][k], f[i-1][2-j][k-1] + a[i][j]); 60 maxit(f[i][j+1][k], f[i-1][4][k-1] + a[i][j]); 61 maxit(f[i][j+1][k], f[i-1][3][k-1] + a[i][j]); 62 } 63 } 64 maxit(f[i][3][k], f[i-1][3][k] + a[i][0] + a[i][1]); 65 maxit(f[i][3][k], f[i-1][0][k] + a[i][0] + a[i][1]); 66 if(k >= 2) maxit(f[i][3][k], f[i-1][4][k-2] + a[i][0] + a[i][1]); 67 maxit(f[i][3][k], f[i-1][1][k] + a[i][0] + a[i][1]); 68 maxit(f[i][3][k], f[i-1][2][k] + a[i][0] + a[i][1]); 69 70 maxit(f[i][4][k], f[i-1][4][k] + a[i][0] + a[i][1]); 71 maxit(f[i][4][k], f[i-1][0][k] + a[i][0] + a[i][1]); 72 if(k) { 73 maxit(f[i][4][k], f[i-1][1][k-1] + a[i][0] + a[i][1]); 74 maxit(f[i][4][k], f[i-1][2][k-1] + a[i][0] + a[i][1]); 75 if(k >= 2) maxit(f[i][4][k], f[i-1][3][k-2] + a[i][0] + a[i][1]); 76 } 77 } 78 } 79 return f[n+1][0][K]; 80 } 81 82 int main() { 83 #ifdef DEBUG 84 freopen("in.txt", "r", stdin); 85 freopen("out.txt", "w", stdout); 86 #endif 87 88 memset(f, -0x3f, sizeof f); 89 f[0][0][0] = 0; 90 scanf("%d%d%d", &n, &m, &K); 91 for(int i = 1; i <= n; i++) { 92 for(int j = 0; j < m; j++) { 93 scanf("%d", a[i] + j); 94 } 95 } 96 if(m == 1) cout << dp1() << endl; 97 else cout << dp2() << endl; 98 99 return 0; 100 }
原文出处http://www.cnblogs.com/showson/