这题的状态转移方程真是粗鄙。
f[i][j][k]表示前i行用了j个矩阵状态为k的时候的最大值。
k=0:两列都不选。
k=1:取左弃右。
k=2:选右弃左。
k=3:左右都选,但分属于两个独立矩阵。
k=4:左右都选,且同属于一个矩阵。
参考题解:孤寂的时代
代码
#include<cstdio> #include<cctype> #include<cstring> inline long long max(long long x,long long y){ return x>y?x:y; } inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch==‘-‘) f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-‘0‘; ch=getchar(); } return num*f; } int f[103][12][6]; int que[1000][5]; int main(){ int n=read(),m=read(),q=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) que[i][j]=read(); memset(f,0xaf,sizeof(f)); for(int i=0;i<=n;++i) for(int j=0;j<=q;++j) f[i][j][0]=0; for(int i=1;i<=n;++i){ int a=que[i][1],b=que[i][2]; for(int j=1;j<=q;++j){ f[i][j][0]=max(max(f[i-1][j][0],f[i-1][j][1]),max(f[i-1][j][2],max(f[i-1][j][3],f[i-1][j][4]))); f[i][j][1]=max(max(max(f[i-1][j-1][0],f[i-1][j][1]),max(f[i-1][j-1][2],f[i-1][j][3]))+a,f[i-1][j-1][4]+a); f[i][j][2]=max(max(max(f[i-1][j-1][0],f[i-1][j-1][1]),max(f[i-1][j][2],f[i-1][j][3]))+b,f[i-1][j-1][4]+b); f[i][j][3]=max(f[i-1][j-1][1],max(f[i-1][j-1][2],f[i-1][j][3]))+a+b; if(j>1) f[i][j][3]=max(f[i][j][3],f[i-1][j-2][4]+a+b); f[i][j][4]=max( max(f[i-1][j-1][0],f[i-1][j-1][1]),max(f[i-1][j-1][2],f[i-1][j-1][3]))+a+b; f[i][j][4]=max(f[i][j][4],f[i-1][j][4]+a+b); } } int ans=f[n][q][1]; if(ans<f[n][q][0]) ans=f[n][q][0]; if(ans<f[n][q][2]) ans=f[n][q][2]; if(ans<f[n][q][3]) ans=f[n][q][3]; if(ans<f[n][q][4]) ans=f[n][q][4]; printf("%d",ans); return 0; }
时间: 2024-10-08 17:54:37