HDU2476:String painter(区间dp)
来源:互联网 发布:淘宝宠爱之名是真的吗 编辑:程序博客网 时间:2024/06/06 00:55
原文地址:http://blog.csdn.net/a601025382s/article/details/12379565
原文作者:knownothing
String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3815 Accepted Submission(s): 1782
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
zzzzzfzzzzzabcdefedcbaababababababcdcdcdcdcdcd
Sample Output
67
题意:给定两个字符串a和b,求最少需要对a进行多少次操作,才能将a变成b。每次操作时将a中任意一段变成任意一个字母所组成的段。
题解:动态规划题。dp[i][j]表示a中i到j段变成b需要的最少次数。递推公式:dp[i][j]=min(dp[i][k]+dp[k+1][j])(i<=k<j)。接着就是判断分界点了,对于字符串b,只有将相同字符一起刷才能减少操作数。所以每次碰到b[i]==b[k]时,可以减少一次操作,因为刷一次[i,k]再刷[i+1,k-1]和分别刷[i,i][k,k],[i+,k,k+1]是一样的,可操作数会减少。
注意:由于如果一段子串两端相等,会成端更新,从而改变中间子串的字符,所以处理时可假定所以a中单个字符都需要一次变化才能变成b。之后动态规划完成后再处理a和b中形同位置相同字符的情况。
另一种理解方式:不考虑起始串,将起始串默认为空串,找出所有dp值(dp[i][j]表示i到j这段空子串转换成目标串需要的最小次数)后,再通过ans[i]来求得最小变换值。ans[i]表示前i+1长度的子串转换成目标串需要的最小次数。
耗时:15MS/2000MS
#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <iostream>#include <algorithm>using namespace std;const int maxn=110;int dp[maxn][maxn];char a[maxn],b[maxn];int ans[maxn];int main(){ while(cin>>a>>b) { int i,j,k,n,m,p,q,len,t; n=strlen(a); memset(dp,0,sizeof(dp)); //为处理方便,一个的时候都需要改变才能得到对应字母。 //因为当一段被更新后,两字符串原本相等的值就改变了。 for(i=0;i<n;i++)dp[i][i]=1; for(len=2;len<=n;len++)//枚举长度 { for(i=0;i<n-len+1;i++)//枚举起点 { j=i+len-1;//终点 //cout<<i<<" "<<j<<endl; dp[i][j]=dp[i+1][j]+1;//!!由于只有比较的是b[i]=b[k],所以不能用dp[i][j]=dp[i][j-1]+1 for(k=i+1;k<=j;k++)//枚举分割点 { if(b[i]==b[k]) { //cout<<i<<" "<<k<<endl; dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); } } } } for(i=0;i<n;i++) ans[i]=dp[0][i]; for(i=0;i<n;i++) { //重新计算两字符串中字符相同的点。 if(a[i]==b[i]) { if(i==0)ans[i]=0; else ans[i]=ans[i-1]; } else { for(j=0;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } } cout<<ans[n-1]<<endl; } return 0;}
0 0
- hdu2476 String painter(区间dp)
- hdu2476 String painter (区间DP)
- HDU2476:String painter(区间dp)
- String painter hdu2476(区间dp)
- HDU2476:String painter(区间DP)
- HDU2476:String painter(区间DP)
- HDU2476 String painter 区间DP
- HDU2476-String painter-区间DP
- HDU2476:String painter 区间dp
- hdu2476 string painter 区间dp
- HDU2476——String painter(区间dp)
- hdu2476——String painter(区间DP)
- HDU2476(String painter)DP
- hdu2476(区间DP)
- hdu2476(区间dp)
- hdu2476(区间DP)
- hdu2476 String painter
- 【HDU2476】【String painter】
- 让你的程序支持https以及https的抓包
- C++复习
- Sizeof与Strlen的区别与联系
- 原生APP中js怎样与Android和ios进行交互
- 深入理解 Java中的 流 (Stream)
- HDU2476:String painter(区间dp)
- 数据库自动重连
- logstash-自启动设置
- Android 之采用execSQL和rawQuery方法完成数据的添删改查操作
- MFC工程 vs2010 C++编译JSONCPP 静态库
- C++事件管理
- 在Linux中虚拟机中安装的XP启用DirectX3D
- 用Python将多个excel表格合并为一个表格
- (十)装饰器模式详解(与IO不解的情缘)