一.闲话
五一收假了,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;
} 
京公网安备 11010502036488号