题目大意:给出一个矩阵,求在这个矩阵中取出k个不重叠的矩阵的最大和。
思路:怎么做?
这个问题困扰我好几天的时间,终于再一次读题:
。。。
。。
。。。
2??!!
这尼玛逗我??直接说最多两列不好么?还用矩阵吓唬我?
好吧下次我一定认真看题。。
我的做法比较渣,算出来的时间复杂度是O(m^3*k),但是只有最多3000w,还是可以过的。
状态:f[i][j][k]表示第一列到了第i个格子,第二列到了第j个格子,已经选取了k个矩阵的最大得数。
转移:先把现有的状态向后转移,转移成f[i‘][j‘][k],然后取矩阵,向后转移,转移成f[i‘][j‘][k + 1]。这里要分三种情况讨论,转移第一列,转移第二列,和两列一起转移。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 110 using namespace std; int m,n,c; int src[MAX][3],sum[3][MAX]; int f[MAX][MAX][15]; int main() { cin >> m >> n >> c; for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) { scanf("%d",&src[i][j]); sum[j][i] = sum[j][i - 1] + src[i][j]; } int ans = 0; if(n == 1) { for(int i = 0; i <= m; ++i) for(int k = 0; k <= c; ++k) for(int _i = i + 1; _i <= m; ++_i) { f[_i][k][0] = max(f[_i][k][0],f[i][k][0]); f[_i][k + 1][0] = max(f[_i][k + 1][0],f[i][k][0] + sum[1][_i] - sum[1][i]); } for(int i = 0; i <= m; ++i) for(int k = 0; k <= c; ++k) ans = max(ans,f[i][k][0]); } else { for(int i = 0; i <= m; ++i) for(int j = 0; j <= m; ++j) for(int k = 0; k <= c; ++k) { for(int _i = i + 1; _i <= m; ++_i) { f[_i][j][k] = max(f[_i][j][k],f[i][j][k]); f[_i][j][k + 1] = max(f[_i][j][k + 1],f[i][j][k] + sum[1][_i] - sum[1][i]); } for(int _j = j + 1; _j <= m; ++_j) { f[i][_j][k] = max(f[i][_j][k],f[i][j][k]); f[i][_j][k + 1] = max(f[i][_j][k + 1],f[i][j][k] + sum[2][_j] - sum[2][j]); } for(int _k = max(i,j) + 1; _k <= m; ++_k) { f[_k][_k][k] = max(f[_k][_k][k],f[i][j][k]); f[_k][_k][k + 1] = max(f[_k][_k][k + 1],f[i][j][k] + sum[1][_k] - sum[1][max(i,j)] + sum[2][_k] - sum[2][max(i,j)]); } } for(int i = 0; i <= m; ++i) for(int j = 0; j <= m; ++j) for(int k = 0; k <= c; ++k) ans = max(ans,f[i][j][k]); } cout << ans << endl; return 0; }
时间: 2024-10-31 05:47:05