一.闲话
五一收假了,qwq好气哦
二.题解
终于做到原题了(雾)
这次就是一个比较简单的dp,只是状态的复杂度。。。(请参考传纸条)
我们设dp[i][j][k][0/1]表示已刷完i-1个木块,第i个木块我们刷了前j个格子,第j个格子是否刷成符合我们需求的颜色,我们一共刷了k次所能获得的
不难发现,我们尽量剩余次数越多,越容易,所以,能一次完成的我们就一次刷完。
于是,对于每个格子我们有讨论:
如果左边格子刷的颜色和当前格子刷的颜色相同,k不变直接转移过来
否则,我们直接重新开始刷一次,则从左边格子的k-1转移过来
注意判断边界条件,也就是j=1的时候,这时,所有转移都来着上个木板,所以,我们必须直接从上个木块的k-1转移过来,即可
代码:
#include<bits/stdc++.h> using namespace std; const int N=51,T=2501; int dp[N][N][T][2],a[N][N]; int main(){ int n,m,t; scanf("%d%d%d",&n,&m,&t); if(!t){ puts("0"); return 0; } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ scanf("%1d",&a[i][j]); } } dp[1][1][1][1]=1,dp[1][1][0][0]=0; int ans=1; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ for(int k=1;k<=t;++k){ if(i==1&&j==1){ continue; } if(j==1){ dp[i][j][k][1]=max(dp[i-1][m][k-1][1],dp[i-1][m][k-1][0])+1; dp[i][j][k][0]=max(dp[i-1][m][k-1][1],dp[i-1][m][k-1][0]); ans=max(ans,max(dp[i][j][k][1],dp[i][j][k][0])); continue; } if(a[i][j]==a[i][j-1]){ dp[i][j][k][1]=max(dp[i][j-1][k-1][0],dp[i][j-1][k][1])+1; dp[i][j][k][0]=max(dp[i][j-1][k-1][1],dp[i][j-1][k][0]); } else{ dp[i][j][k][1]=max(dp[i][j][k][1],max(dp[i][j-1][k][0],dp[i][j-1][k-1][1])+1); dp[i][j][k][0]=max(dp[i][j][k][0],max(dp[i][j-1][k][1],dp[i][j-1][k-1][0])); } ans=max(ans,max(dp[i][j][k][1],dp[i][j][k][0])); } } } printf("%d",ans); return 0; }