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 }

 

posted @ 2015-12-08 10:38  Showson  阅读(121)  评论(0编辑  收藏