您的位置:首页 > 其它

[bzoj1084][SCOI2005]最大子矩阵 dp

2017-10-18 19:27 351 查看

1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB

[Submit][Status][Discuss]

Description

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

不能相互重叠。

Input

  第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的

分值的绝对值不超过32767)。

Output

  只有一行为k个子矩阵分值之和最大为多少。

Sample Input

3 2 2

1 -3

2 3

-2 3

Sample Output

9

HINT

数据只有两行
dp[i][j][k]遍历到第一行i个,第二行j个,生成了k个矩形
1行特判,好像不好优化的样子
我开始竟然搞忘写两行的情况了,naive
#include <bits/stdc++.h>
using namespace std;
int n, m, k, f[105][15], dp[105][105][15], s1[105], s2[105];
int main(){
scanf( "%d%d%d", &n, &m, &k );
if( m == 1 ){
for( int i = 1, x; i <= n; i++ ) scanf( "%d", &x ), s1[i] = s1[i-1] + x;
for( int i = 1; i <= n; i++ )
for( int l = 1; l <= k; l++ ){
f[i][l] = f[i-1][l];
for( int j = 0; j < i; j++ )
f[i][l] = max( f[j][l-1] + s1[i] - s1[j], f[i][l] );
}
printf( "%d\n", f
[k] );
}else{
for( int i = 1, x, y; i <= n; i++ )
scanf( "%d%d", &x, &y ), s1[i] = s1[i-1] + x, s2[i] = s2[i-1] + y;
for( int l = 1; l <= k; l++ )
for( int i = 1; i <= n; i++ )
for( int j = 1; j <= n; j++ ){
dp[i][j][l] = max( dp[i-1][j][l], dp[i][j-1][l] );
for( int p = 0; p < i; p++ )
dp[i][j][l] = max( dp[p][j][l-1] + s1[i] - s1[p], dp[i][j][l] );
for( int p = 0; p < j; p++ )
dp[i][j][l] = max( dp[i][p][l-1] + s2[j] - s2[p], dp[i][j][l] );
if( i == j ){
for( int p = 0; p < i; p++ )
dp[i][j][l] = max( dp[i][j][l],
dp[p][p][l-1] + s1[i] - s1[p] + s2[i] - s2[p] );
}
}
printf( "%d\n", dp

[k] );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: