这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
标签:

最多只有2列..分开来dp
1列 dp(x, k) = max( dp(x - 1, k), dp(p, k - 1) + sum(p+1~x) )
2列 dp(a, b, k) = max( dp(a - 1, b, k), dp(a, b - 1, k), dp(p, b, k - 1) + sum1(p+1~a), dp(a, p, k - 1) + sum2(p+1~b) ) 当a = b, dp(a, b, k)还可以用dp(p, p, k - 1) + SUM(p+1~a) (0 ≤ p < a)更新
#include<bits/stdc++.h>
using namespace std;
const int maxk = 19;
const int maxn = 109;
int N, K;
namespace one {
int sum[maxn], dp[maxn][maxk];
void init() {
sum[0] = 0;
for(int i = 1; i <= N; i++) {
scanf("%d", sum + i);
sum[i] += sum[i - 1];
}
}
void work() {
init();
memset(dp, 0, sizeof dp);
for(int i = 0; i < N; i++) {
for(int k = 0; k <= K; k++)
dp[i + 1][k] = max(dp[i + 1][k], dp[i][k]);
for(int k = 1; k <= K; k++)
for(int j = i + 1; j <= N; j++)
dp[j][k] = max(dp[j][k], dp[i][k - 1] + sum[j] - sum[i]);
}
printf("%d\n", dp[N][K]);
}
}
namespace two {
int sum[2][maxn], dp[maxn][maxn][maxk];
void init() {
sum[0][0] = sum[1][0] = 0;
for(int j = 1; j <= N; j++)
for(int i = 0; i < 2; i++) {
scanf("%d", &sum[i][j]);
sum[i][j] += sum[i][j - 1];
}
}
void work() {
init();
memset(dp, 0, sizeof dp);
for(int i = 0; i <= N; i++)
for(int j = 0; j <= N; j++) if(i + j < N * 2) {
for(int k = 0; k <= K; k++) {
if(i < N) dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]);
if(j < N) dp[i][j + 1][k] = max(dp[i][j + 1][k], dp[i][j][k]);
}
for(int k = 1; k <= K; k++)
for(int _i = i; _i <= N; _i++)
for(int _j = j; _j <= N; _j++) if(_i + _j > i + j) {
dp[_i][_j][k] = max(dp[_i][_j][k], dp[i][_j][k - 1] + sum[0][_i] - sum[0][i]);
dp[_i][_j][k] = max(dp[_i][_j][k], dp[_i][j][k - 1] + sum[1][_j] - sum[1][j]);
}
if(i == j) {
for(int k = 0; k <= K; k++)
dp[i + 1][j + 1][k] = max(dp[i + 1][j + 1][k], dp[i][j][k]);
for(int _i = i + 1; _i <= N; _i++)
for(int k = 1; k <= K; k++)
dp[_i][_i][k] = max(dp[_i][_i][k], dp[i][j][k - 1] + sum[0][_i] - sum[0][i] + sum[1][_i] - sum[1][j]);
}
}
printf("%d\n", dp[N][N][K]);
}
}
int main() {
int m;
cin >> N >> m >> K;
m == 1 ? one::work() : two::work();
return 0;
}
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
只有一行为k个子矩阵分值之和最大为多少。
BZOJ 1084: [SCOI2005]最大子矩阵( dp )
标签:
原文地址:http://www.cnblogs.com/JSZX11556/p/4732568.html