String painter,区间dp
String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11069 Accepted Submission(s): 5416
Problem Description
There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?
Input
Input contains multiple cases. Each case consists of two lines:
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
Output
A single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
Sample Output
6
7
Source
解析 :
可以先将一个空串转化成B,再比较与将A直接转化成B那个更快;
子集划分:令dp[i][j]为将[i, j]区间转换成功最少操作数;
最坏的情况下,是将每个字符都变一下,dp[i][i]=1;区间[i, i+1]是由[i, i]扩展来的,dp[i][i+1]=dp[i][i]+1;同理:dp[i][j]=dp[i][j-1]+1;然后在区间[i, j]中如果有一个B[k]==B[j]那么dp[i][j]=min(dp[i][j], dp[i][k-1]+dp[k][j-1]);这一步是如何来的呢?
[i, j]区间可以看作[i, k-1]+[k, j-1],当B[j]==B[k]时,所以先[k, j]全转换成1种字符,再将[k+1, j-1]转换,相当于只转化了[k, j-1];
注意,这里不要写成dp[k+1][j-1]+1, 因为dp[k][j-1]可能更小;
ans[i]表示A的[1, i]区间转换成B的[1, i]的最少操作
ans[i]=min(ans[i], ans[k]+dp[k+1][i])(0<=k<=i);
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
typedef long long LL;
const int N = 1e2 + 5;
int n;
char a[N], b[N];
int f[N][N],ans[N];
int main() {
while (scanf("%s%s",a+1,b+1)!=EOF) {
n = strlen(a+1);
memset(f, 0, sizeof f);
for (int i = 1; i <= n; i++)
f[i][i] = 1;
for (int len = 2; len <= n; len++) {
for (int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1;
f[i][j] = f[i][j-1] + 1;
for (int k = i-1; k < j; k++) {
if (b[k] == b[j])
f[i][j] = min(f[i][j], f[i][k-1] + f[k][j - 1]);
}
}
}
for (int i = 1; i <= n; i++) {
ans[i] = f[1][i];
}
for (int i = 1; i <= n; i++) {
if (a[i] == b[i]) {
ans[i] = ans[i - 1];
}
else {
for (int j = 1; j < i; j++) {
ans[i] = min(ans[j] + f[j + 1][i], ans[i]);
}
}
}
cout << ans[n] << endl;
}
return 0;
}
分类:
dp / # 区间dp
标签:
动态规划
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】