HDU 2476 区间DP--转移思考方向
2017-08-03 22:27
501 查看
区间DP–转移思考方向
题意:有两个字符串,现在有一个操作可以把第一个字字符串的某区间改成同一个字母,问最少多少步可以变成第二个字符串。
思路:
思考问题的方向,关键点在于有的区间端点相同的话可以直接一步操作,问题是很难直接用区间DP去比较两个字符串,四维的不行。换一种思考方式,如果能先把最坏的情况算出来,也就是直接构造一个字符串2的最少步数算出,就可以再找出特殊情况,所以对s2DP,从后往前,长度依次增大,每次寻找最少的步数,当然需要初始化。很多博客上对dp[i][j]=dp[i+1][j]+1; 不太清晰,其实在DP的时候是从后往前的,每次相当于增添了第i个字母,最坏当然是只改变一个第i区间了,而dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); 的意义在于如果第i个字母与后边的某一个字母相同的话可以利用已经算出的结果,把后边的去区间分为两部分,因为第i和第k在区间转换字母的时候只需一次就行
所以记录最小的就行。
区间DP很重要的一点就是每次计算都在已经找的区间种选择最小的期望值,利用的是已经算出的结果。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 1005; int dp[maxn][maxn]; char s1[maxn],s2[maxn]; int ans[maxn]; int main(int argc, char const *argv[]) { //freopen("in.txt","r",stdin); while(scanf("%s%s",s1,s2) != EOF) { int len = strlen(s2); for(int i = 0;i < len; i++) { for(int j = i;j < len; j++) { dp[i][j] = j - i + 1; } } for(int i = len-2;i >= 0; i--) { for(int j = i;j < len; j++) { dp[i][j] = dp[i+1][j] + 1; for(int k = i + 1;k <= j; k++) { if(s2[i] == s2[k]) { dp[i][j] = min(dp[i][j] , dp[i+1][k] + dp[k+1][j]); } } } } for(int i = 0;i < len; i++) ans[i] = dp[0][i]; for(int i = 0;i < len; i++) { if(s1[i] == s2[i]) { if(i == 0) ans[0] = 0; else ans[i] = ans[i-1]; } for(int j = 0;j < i; j++) { ans[i] = min(ans[i],ans[j] + dp[j+1][i]); } } printf("%d\n",ans[len-1]); } return 0; }
相关文章推荐
- hdu 2476 String painter(区间dp)
- HDU - 2476 String painter 区间dp预处理+dp
- HDU 2476 区间DP
- HDU 2476 String painter(区间DP)
- HDU 2476 String painter (*区间DP+基础Dp)
- HDU 2476 String painter (区间DP)
- HDU 2476 String painter(区间DP)
- HDU2476——String painter(区间dp)
- HDU 2476 String painter (区间DP)
- HDU_2476_String painter_(区间dp)
- Hdu 2476 String painter(区间dp)
- HDU 2476 String painter(区间dp)
- hdu 2476 String painter (区间dp)
- hdu 2476 String painter(区间dp)
- HDU 2476 String painter(区间DP)
- HDU 2476:String painter (区间DP)
- HDU 2476 String painter 刷字符串(区间DP)
- HDU 2476 String painter(区间DP)
- HDU 2476 | UVALive 4394 - String painter (区间DP)
- HDU 2476 String painter(区间DP)@