Time Limit: 10 Sec
Memory Limit: 162 MB
Description
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵,不能相互重叠。
Input
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
Output
只有一行为k个子矩阵分值之和最大为多少。
题目分析
注意到 m < = 2 m<=2 m<=2,所以可以从依靠m分类讨论
当
m
=
=
1
m==1
m==1时,相当于在一排数中选出
k
k
k个连续子段,使其和最大
d
p
[
i
]
[
j
]
[
0
/
1
]
dp[i][j][0/1]
dp[i][j][0/1]分别表示前
i
i
i个数分了
j
j
j组,且第
i
i
i个数不取(0)/取(1)所能得的最大值
那么有
dp[i,j,0]=max(dp[i-1,j,0],dp[i-1,j,1]);
dp[i,j,1]=max(dp[i-1,j-1,0],dp[i-1,j-1,1],dp[i-1,j,1])+a[i];
再考虑
m
=
=
2
m==2
m==2,这种情况就比较恶心了
d
p
[
i
]
[
j
]
[
0
]
dp[i][j][0]
dp[i][j][0] 前
i
i
i行分了
j
j
j组,且第
i
i
i行两个都不选
d
p
[
i
]
[
j
]
[
1
]
dp[i][j][1]
dp[i][j][1] 前
i
i
i行分了
j
j
j组,且第
i
i
i行两个都选 ,第
i
i
i行两个数在同一个矩阵内
d
p
[
i
]
[
j
]
[
2
]
dp[i][j][2]
dp[i][j][2] 前
i
i
i行分了
j
j
j组,且第
i
i
i行两个都选 ,第
i
i
i行两个数不在同一个矩阵内
d
p
[
i
]
[
j
]
[
3
]
dp[i][j][3]
dp[i][j][3] 前
i
i
i行分了
j
j
j组,且第
i
i
i行只选左边的
d
p
[
i
]
[
j
]
[
4
]
dp[i][j][4]
dp[i][j][4] 前
i
i
i行分了
j
j
j组,且第
i
i
i行只选右边的
dp数组定义都这么多,那么显然dp方程一定会更恶心
dp[i,j,0]=max( dp[i-1,j,0], dp[i-1,j,1], dp[i-1,j,2], dp[i-1,j,3], dp[i-1,j,4] )
dp[i,j,1]=max( dp[i-1,j-1,0], dp[i-1,j,1], dp[i-1,j-1,1], dp[i-1,j-1,2], dp[i-1,j-1,3], dp[i-1,j-1,4] )+a[i][1]+a[i][2]
dp[i,j,2]=max( dp[i-1,j-2,0], dp[i-1,j-2,1], dp[i-1,j-2,2], dp[i-1,j-1,2], dp[i-1,j,2],
dp[i-1,j-1,3], dp[i-1,j-1,4], dp[i-1,j-2,3], dp[i-1,j-2,4] )+a[i][1]+a[i][2]
dp[i,j,3]=max( dp[i-1,j-1,0], dp[i-1,j-1,1], dp[i-1,j-1,2], dp[i-1,j,2],
dp[i-1,j-1,3], dp[i-1,j,3], dp[i-1,j-1,4] )+a[i][1]
dp[i,j,4]=max( dp[i-1,j-1,0], dp[i-1,j-1,1], dp[i-1,j-1,2], dp[i-1,j,2],
dp[i-1,j-1,3], dp[i-1,j-1,4], dp[i-1,j,4] )+a[i][2]
调了半个多小时看着这些方程眼睛都瞎了(Φ皿Φ)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int read()
{
int x=0,f=1;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
const int maxn=150;
int n,m,k;
int a[maxn][5],dp[maxn][15][10];
int main()
{
n=read();m=read();k=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
a[i][j]=read();
memset(dp,128,sizeof(dp));
for(int i=0;i<=n;++i)
for(int j=0;j<=k;++j)
dp[i][j][0]=0;
if(m==1)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=k;++j)
{
dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]);
dp[i][j][1]=max(max(dp[i-1][j-1][0],dp[i-1][j-1][1]),dp[i-1][j][1])+a[i][1];
}
printf("%d",max(dp[n][k][0],dp[n][k][1]));
return 0;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=k;++j)
{
dp[i][j][0]=max( dp[i][j][0], max(dp[i-1][j][0],dp[i-1][j][1]) );
dp[i][j][0]=max( dp[i][j][0], max(dp[i-1][j][2],dp[i-1][j][3]) );
dp[i][j][0]=max( dp[i][j][0], dp[i-1][j][4]);
dp[i][j][1]=max( dp[i][j][1], max(dp[i-1][j-1][0],dp[i-1][j][1])+a[i][1]+a[i][2] );
dp[i][j][1]=max( dp[i][j][1], max(dp[i-1][j-1][1],dp[i-1][j-1][2])+a[i][1]+a[i][2] );
dp[i][j][1]=max( dp[i][j][1], max(dp[i-1][j-1][3],dp[i-1][j-1][4])+a[i][1]+a[i][2] );
if(j>=2) dp[i][j][2]=max( dp[i][j][2], max(dp[i-1][j-2][0],dp[i-1][j-2][1])+a[i][1]+a[i][2] );
if(j>=2) dp[i][j][2]=max( dp[i][j][2], dp[i-1][j-2][2]+a[i][1]+a[i][2] );
dp[i][j][2]=max( dp[i][j][2], max(dp[i-1][j-1][2],dp[i-1][j][2])+a[i][1]+a[i][2] );
dp[i][j][2]=max( dp[i][j][2], max(dp[i-1][j-1][3],dp[i-1][j-1][4])+a[i][1]+a[i][2] );
if(j>=2)dp[i][j][2]=max( dp[i][j][2], max(dp[i-1][j-2][3],dp[i-1][j-2][4])+a[i][1]+a[i][2] );
dp[i][j][3]=max( dp[i][j][3], max(dp[i-1][j-1][0],dp[i-1][j-1][1])+a[i][1] );
dp[i][j][3]=max( dp[i][j][3], max(dp[i-1][j-1][2],dp[i-1][j][2])+a[i][1] );
dp[i][j][3]=max( dp[i][j][3], max(dp[i-1][j-1][3],dp[i-1][j][3])+a[i][1] );
dp[i][j][3]=max( dp[i][j][3], dp[i-1][j-1][4]+a[i][1] );
dp[i][j][4]=max( dp[i][j][4], max(dp[i-1][j-1][0],dp[i-1][j-1][1])+a[i][2] );
dp[i][j][4]=max( dp[i][j][4], max(dp[i-1][j-1][2],dp[i-1][j][2])+a[i][2] );
dp[i][j][4]=max( dp[i][j][4], dp[i-1][j-1][3]+a[i][2] );
dp[i][j][4]=max( dp[i][j][4], max(dp[i-1][j-1][4],dp[i-1][j][4])+a[i][2] );
}
int ans=-1e9;
ans=max(ans,dp[n][k][0]); ans=max(ans,dp[n][k][1]);
ans=max(ans,dp[n][k][2]); ans=max(ans,dp[n][k][3]);
ans=max(ans,dp[n][k][4]);
if(ans<0) ans=0;
printf("%d",ans);
return 0;
}