标签:String s2 s1 更新 maxn painter 字符串 dp
区间dp H - String painter
题目大意:
给你两个字符串 \(s1\) 和 \(s2\) ,你每次可以对一段区间更新成同一种颜色,问最少更新多少次可以把 \(s1\) 更新成 \(s2\)
题解:
- 首先把这个当成一个空白字符串进行求解,这个B - Halloween Costumes 已经写过如何求解
- 然后在对于两个不同的字符串具体进行操作使得最后的更新次数比更新一个空白字符串要少。
- 对于位置 \(i\) 如果 \(s1[i]==s2[i]\) 则此时的更新次数就等于到 \(i-1\) 这位置的更新次数
- 如果 \(s1[i]!=s2[i]\) 那么此时的更新次数等于:\(i\) 之前的一个位置 \(j\) 的次数+\(dp[i][j]\)
如果已经一个字符串更新成我需要的字符串的最少次数,那么对于一个已知的字符串,想要更新成需要的字符串,这个问题就是一个简单的 \(dp\)。
这个题目和B - Halloween Costumes 这个题目相比较,两个题目很像,只是本题已经给了一个字符串了,所以可能可以减少这个更新的次数。
自己没有想清楚,如果之前的哪个题目会写了,这个题目应该也要会写才对。
#include <bits/stdc++.h>
#define id first
#define val second
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=110;
typedef long long ll;
int dp[maxn][maxn],f[maxn];
char s1[maxn],s2[maxn];
void init(int n){
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++) dp[i][j]=0;
}
}
int main(){
while(scanf("%s%s",s1+1,s2+1)!=EOF){
int n=strlen(s1+1);
init(n);
for(int i=1;i<=n;i++) {
dp[i][i]=1;
}
for(int len=2;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
dp[i][j]=dp[i+1][j]+1;
for(int k=i+1;k<=j;k++){
if(s2[k]==s2[i]) dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);
}
}
}
for(int i=1;i<=n;i++){
f[i] = i;
if (s1[i] == s2[i]) f[i] = f[i - 1];
else {
for (int j = 1; j <= i; j++)
f[i] = min(f[i], f[j - 1] + dp[j][i]);
}
}
printf("%d\n", f[n]);
}
return 0;
}
标签:String,s2,s1,更新,maxn,painter,字符串,dp 来源: https://www.cnblogs.com/EchoZQN/p/13281298.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。