粉刷匠(字符串的dp问题)
作者:互联网
windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。
windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。 链接:https://ac.nowcoder.com/acm/problem/20273输入描述:
输入文件paint.in第一行包含三个整数,N M T。
接下来有N行,每行一个长度为M的字符串,'0'表示红色,'1'表示蓝色。
输出描述:
输出文件paint.out包含一个整数,最多能正确粉刷的格子数。示例1
输入
复制3 6 3 111111 000000 001100
输出
复制16
最近接触了几道字符串dp问题感觉大多都是用区间dp进行,但在这个涉及到多组字符串,故应该考虑多维。
#include<bits/stdc++.h> using namespace std; int N,M,T; string str[55]; int dp[55][55][2555][2];//行 位置 操作次数 正确与否 int main() { cin>>N>>M>>T; for(int i=1;i<=N;i++) cin>>str[i]; memset(dp,0,sizeof(dp)); int maxz=0; for(int i=1;i<=N;i++) { for(int j=0;j<M;j++) { for(int k=1;k<=T;k++) { if(j==0) { dp[i][j][k][1]=max(dp[i-1][M-1][k-1][0],dp[i-1][M-1][k-1][1])+1;//与上一行k-1操作时候连接 dp[i][j][k][0]=max(dp[i-1][M-1][k-1][0],dp[i-1][M-1][k-1][1]); } else if(str[i][j]==str[i][j-1]) { dp[i][j][k][1]=max(dp[i][j-1][k-1][0],dp[i][j-1][k][1])+1;//因为上次错误,故一定不是一步,应该为k-1步 dp[i][j][k][0]=max(dp[i][j-1][k][0],dp[i][j-1][k-1][1]); } else { 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-1][k][1],dp[i][j-1][k-1][0]); } } maxz=max(maxz,max(dp[i][j][T][1],dp[i][j][T][0])); } } cout<<maxz<<endl; }
标签:格子,int,粉刷,55,windy,字符串,dp 来源: https://www.cnblogs.com/Charls/p/12830070.html