bzoj 1296: [SCOI2009]粉刷匠
思路:两次dp, 第一次行内, 第二次行间, 刚开始读错题。。要死了。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define piii pair<int, pair<int,int>> 8 9 using namespace std; 10 11 const int N = 50 + 7; 12 const int M = 1e4 + 7; 13 const int inf = 0x3f3f3f3f; 14 const LL INF = 0x3f3f3f3f3f3f3f3f; 15 const int mod = 1e9 + 7; 16 17 char s[N][N]; 18 int f[N][N][2], dp[N][2501], v[N][N], n, m, t; 19 int main() { 20 scanf("%d%d%d", &n, &m, &t); 21 for(int i = 1; i <= n; i++) 22 scanf("%s", s[i] + 1); 23 24 for(int k = 1; k <= n; k++) { 25 memset(f, 0, sizeof(f)); 26 for(int i = 1; i <= m; i++) { 27 for(int j = 1; j <= m; j++) { 28 f[i][j][0] = f[i - 1][j][0]; 29 f[i][j][1] = f[i - 1][j][1]; 30 31 if(s[k][i] == '1') { 32 f[i][j][1] = max(f[i][j][1], f[i - 1][j][1] + 1); 33 f[i][j][1] = max(f[i][j][1], f[i - 1][j - 1][0] + 1); 34 } else { 35 f[i][j][0] = max(f[i][j][0], f[i - 1][j][0] + 1); 36 f[i][j][0] = max(f[i][j][0], f[i - 1][j - 1][1] + 1); 37 } 38 } 39 40 } 41 for(int j = 1; j <= m; j++) { 42 v[k][j] = max(f[m][j][0], f[m][j][1]); 43 v[k][j] = max(v[k][j], v[k][j - 1]); 44 } 45 } 46 47 int ans = 0; 48 for(int i = 1; i <= n; i++) { 49 for(int j = 1; j <= t; j++) { 50 for(int k = 0; k <= m && j - k >= 0; k++) { 51 dp[i][j] = max(dp[i][j], dp[i - 1][j - k] + v[i][k]); 52 } 53 ans = max(ans, dp[i][j]); 54 } 55 } 56 57 printf("%d\n", ans); 58 return 0; 59 } 60 61 /* 62 */