HDU2476-String painter-区间DP
2014-10-13 16:59
323 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2476
两篇博客综合这看, 总算是理解了, 我这里把两篇博客整合一下.原文如下:
/article/2388182.html
/article/9867139.html
dp[i][j]表示str1[i ... j]刷成str2[i ... j]所用的最少操作次数.
初始化:dp[i][j] = dp[i + 1][j ]+ 1;
①str1与str2完全不同:
对于str2来说:
k = (i + 1 ... j );
如果str2[k]==str2[i], 则dp[i][j]=min(dp[i][j],dp[i + 1][k]+dp[k + 1][j]), 因为刷str1[i]的时候可以与str1[k]同时刷, 即刷已i结尾的区间时, 将str1[i ... k]也一起刷了
②str1与str2有部分相同:
ans[i]: 表示将str1[0...i]刷成str2[0...i]的最小步数, 根据ans[i]的定义得到ans[i]的初始化为:ans[i] = dp[0][i];
if(str1[i]==str2[i])
ans[i]=ans[i-1];
else
ans[i]=min(ans[i], ans[j]+dp[j + 1][i]) j = 0...i;
参考着代码会比较容易理解一些, 代码里将①与dp的初始化放在一起了, 因为每次初始化的区间与①操作的区间时相同的.
用来初始化的两层循环, 看着可能有点别扭, 可能很多人更喜欢下面这种风格
for(int i = 0; i < n; ++i)
for(int j = i; j >=0; --j)
dp[i][j] = dp[i][j + 1] + 1;
我当时看的时候就别扭了好久, 那样写也是为了方便里面的第三层循环.
两篇博客综合这看, 总算是理解了, 我这里把两篇博客整合一下.原文如下:
/article/2388182.html
/article/9867139.html
dp[i][j]表示str1[i ... j]刷成str2[i ... j]所用的最少操作次数.
初始化:dp[i][j] = dp[i + 1][j ]+ 1;
①str1与str2完全不同:
对于str2来说:
k = (i + 1 ... j );
如果str2[k]==str2[i], 则dp[i][j]=min(dp[i][j],dp[i + 1][k]+dp[k + 1][j]), 因为刷str1[i]的时候可以与str1[k]同时刷, 即刷已i结尾的区间时, 将str1[i ... k]也一起刷了
②str1与str2有部分相同:
ans[i]: 表示将str1[0...i]刷成str2[0...i]的最小步数, 根据ans[i]的定义得到ans[i]的初始化为:ans[i] = dp[0][i];
if(str1[i]==str2[i])
ans[i]=ans[i-1];
else
ans[i]=min(ans[i], ans[j]+dp[j + 1][i]) j = 0...i;
参考着代码会比较容易理解一些, 代码里将①与dp的初始化放在一起了, 因为每次初始化的区间与①操作的区间时相同的.
用来初始化的两层循环, 看着可能有点别扭, 可能很多人更喜欢下面这种风格
for(int i = 0; i < n; ++i)
for(int j = i; j >=0; --j)
dp[i][j] = dp[i][j + 1] + 1;
我当时看的时候就别扭了好久, 那样写也是为了方便里面的第三层循环.
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <algorithm> #include <string> #include <queue> #include <stack> #include <vector> #include <list> #include <map> #include <set> #include <iomanip> #define CL(x,v); memset(x,v,sizeof(x)); #define INF 1<<29 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int N = 100 + 5; char str1 , str2 ; int dp , ans ; int main() { while(~scanf("%s%s", str1, str2)) { CL(dp, 0); CL(ans, 0); int len = strlen(str1); for(int j = 0; j < len; ++j) { for(int i = j; i >= 0; --i) //i是操作区间的开头, j是操作区间的结尾 { dp[i][j] = dp[i + 1][j] + 1; for(int k = i + 1; k <= j; ++k) { if(str2[k] == str2[i]) dp[i][j] = min(dp[i][j], dp[i + 1][k] + dp[k + 1][j]);//dp[i + 1][k] + dp[k + 1][j] 将dp[i][j]分解为两段之和 } } } for(int i = 0; i < len; ++i) ans[i] = dp[0][i]; //初始化ans[i] for(int i = 0; i < len; ++i) if(str1[i] == str2[i]) ans[i] = ans[i - 1]; else for(int j = 0; j < i; ++j) ans[i] = min(ans[i], ans[j] + dp[j + 1][i]); //ans[j] + dp[j + 1][i] 将ans[i]分解为两段之和 printf("%d\n", ans[len - 1]); } return 0; }
相关文章推荐
- 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+字符串处理
- HDU 2476 String painter(区间DP)
- hdu 2476 String painter 区间dp
- LA 4394 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,08成都现场赛题)