[SCOI2005]最大子矩阵

来源:互联网 发布:怎样在电脑上开淘宝店 编辑:程序博客网 时间:2024/05/16 11:05
[SCOI2005]最大子矩阵
题目描述
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
输入输出格式
输入格式:
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
输出格式:
只有一行为k个子矩阵分值之和最大为多少。
输入输出样例
输入样例#1:
3 2 21 -32 3-2 3
输出样例#1:
9

题解:
由于m<=2那么每一行只有5个状态。
1.一个数也不选:f[i][j][0]=max(max(f[i-1][j][0],f[i-1][j][4]),max(f[i-1][j][1],max(f[i-1][j][2],f[i-1][j][3])));
2.选第一个数:f[i][j][1]=max(max(tmp,f[i-1][j][1]),f[i-1][j][4])+a[i][1];
3.选第二个数:f[i][j][2]=max(max(tmp,f[i-1][j][2]),f[i-1][j][4])+a[i][2];
4.两个数都选且位于一个矩阵中:f[i][j][3]=max(tmp,f[i-1][j][3])+a[i][3];
5.两个数都选但位于两个不同矩阵中:if(j>=2) f[i][j][4]=max(max(f[i-1][j-2][0],f[i-1][j][4]),max(f[i-1][j-1][1],f[i-1][j-1][2]))+a[i][3];
代码:
#include<bits/stdc++.h>using namespace std;const int max_n = 101;const int inf = 1e9+7;int w[5][max_n][max_n],a[max_n][5];int f[max_n][max_n][5];int n,m,t,ans;inline void dp(){for(int i=1; i<=n; ++i)  for(int j=1; j<=t; ++j)  {  int tmp=max(max(f[i-1][j-1][0],f[i-1][j-1][1]),max(max(f[i-1][j-1][2],f[i-1][j-1][3]),f[i-1][j-1][4]));   f[i][j][0]=max(max(f[i-1][j][0],f[i-1][j][4]),max(f[i-1][j][1],max(f[i-1][j][2],f[i-1][j][3])));   f[i][j][1]=max(max(tmp,f[i-1][j][1]),f[i-1][j][4])+a[i][1];   f[i][j][2]=max(max(tmp,f[i-1][j][2]),f[i-1][j][4])+a[i][2];   f[i][j][3]=max(tmp,f[i-1][j][3])+a[i][3];   if(j>=2) f[i][j][4]=max(max(f[i-1][j-2][0],f[i-1][j][4]),max(f[i-1][j-1][1],f[i-1][j-1][2]))+a[i][3];  }}int main(){scanf("%d%d%d",&n,&m,&t);for(int i=1; i<=n; ++i)  for(int j=1; j<=m; ++j)  {    scanf("%d",&a[i][j]);a[i][3]+=a[i][j];  }dp();ans=max(max(f[n][t][0],max(f[n][t][1],f[n][t][2])),max(f[n][t][3],f[n][t][4]));printf("%d\n",ans);return 0;}



原创粉丝点击