uva live 4394 String painter 区间dp

来源:互联网 发布:可口可乐表白软件 编辑:程序博客网 时间:2024/04/30 20:58
// uva live 4394 String painter//// 这一题是训练指南上dp专题的习题,初看之下觉得只是略微复杂了一点// 就敲阿敲阿敲,两个半小时后,发现样例过了,然而自己给出的数据跪了// 交了也wa了,才发现,自己的方法是有问题的,如果是将两个串同时考虑// 的话,比如: dp[i][j] 表示从i到j,s串刷成目标b串所需要的最小的花费// 然后根据区间的端点的字符特点,进行状态转移,然而可能是我太搓了,// 发现这样的状态转移是不对的,比如edc和cde,按照我d方法算出来是3,// 这时,我想到了先处理出如果 d[i][i] = (s[i]==b[i]) ? 0 : 1,这样处理// 出来确实是2,然而对于样例// zzzzzfzzzzz// abcdefedcba// 显然,按照我的方法是5,默认f不用刷。//// 仔细想来,如果状态是这样定义的话,那么状态转移就会非常麻烦,因为后面// 的状态可能并不是当前状态所能转移过去的,要加上额外的开销,至于这个// 开销是什么,我依然没弄明白,如果有大神能指点一二,那小子双手奉上// 2.56$,并致以最为诚挚的感激。//// 最后看了看网上的题解,思路几乎都是一样的,构造dp + 线性dp// 首先不考虑s串与b串之间的联系。// dp[i][j]表示从空串刷成b串所需要的最小的花费。// dp[i][j] = dp[i][k] + dp[k+1][j]{ i <= k < j}// 如果b[i] == b[j],那么dp[i][j] = dp[i][j-1],此时b[j]完全可以由i到j-1// 刷出来。//// 最后f[i]表示1到i,s串变成b串所需要的最小花费// 如果s[i] == b[i] 那么肯定 f[i] = f[i-1];// 否则f[i] = min(f[j] + dp[j+1][i]);//// 这样最后的f[n]我们所求的答案。//// 这题,我感觉我最终学会的是:如果一个问题是一个很复杂的问题,要// 考虑很多个方面,那么我们可以尝试分段求解,这样或许就能更加接近// 正确的答案。继续练////const int maxn = 108;//const int inf = 0x4f4f4f4f;//char s[maxn];//char b[maxn];//int d[maxn][maxn];//bool vis[maxn][maxn];//int n;//int cost[maxn][maxn];//int dp(int x,int y){//if (vis[x][y])return d[x][y];//vis[x][y] = 1;//if (x==y){//d[x][y] = 1;//return d[x][y];//}//if (x>y)return d[x][y] = inf;//int& ans = d[x][y];//ans = inf;////////for (int k=x;k<y;k++){//ans = min(ans,dp(x,k)+dp(k+1,y));//}////if (b[x]==b[y]){//ans = min(ans,dp(x,y-1));//}//////////if (s[x]==b[x] && s[y]==b[y]){////ans = min(ans,dp(x+1,y-1));////}////if (b[x]==b[y]){////ans = min(ans,dp(x,y-1));////ans = min(ans,dp(x+1,y));////}////////temp = x;////while(b[temp]==b[y] && temp < y){////temp++;////}////ans = min(ans,dp(temp,y));////temp = y;////////while(b[x]==b[temp] && temp > x){////temp--;////}////ans = min(ans,dp(x,temp));////////temp = x;////////while(b[temp]==b[temp+1]&&temp<y){////temp++;////}////////if (temp!=x)////ans = min(ans,dp(temp,y));////////temp = y;////while(b[temp]==b[temp-1]&&temp>x){////temp--;////}////if (temp!=y)////ans = min(ans,dp(x,temp));//////return ans;//}////void print(){//for (int i=0;i<n;i++){//for (int j=0;j<n;j++){//if (d[i][j]==inf)//d[i][j] = 0;//printf("%d ",d[i][j]);//}//puts("");//}//}////bool same(){//for (int i=1;i<=n;i++)//if (s[i]!=b[i])//return false;//return true;//}////void init(){//memset(d,inf,sizeof(d));//memset(vis,0,sizeof(vis));//memset(cast,0,sizeof(cast));//n = strlen(s+1);//if (same()){//printf("0\n");//return ;//}////int cnt = 0;//for (int i=1;i<=n;i++){//if (s[i]==b[i]){//cnt++;//}//cost[i] = cnt;//}////printf("%d\n",dp(1,n));//print();//}////int main() {//freopen("E:\\Code\\1.txt","r",stdin);//while(scanf("%s%s",s+1,b+1)!=EOF){//init();////solve();//}//return 0;//}#include <algorithm>#include <bitset>#include <cassert>#include <cctype>#include <cfloat>#include <climits>#include <cmath>#include <complex>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <functional>#include <iostream>#include <list>#include <map>#include <numeric>#include <queue>#include <set>#include <stack>#include <vector>#define ceil(a,b) (((a)+(b)-1)/(b))#define endl '\n'#define gcd __gcd#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))#define popCount __builtin_popcountlltypedef long long ll;using namespace std;const int MOD = 1000000007;const long double PI = acos(-1.L);const int maxn = 108;char s[maxn];char b[maxn];int d[maxn][maxn];int f[maxn];int n;int vis[maxn][maxn];const int inf = 0x1f1f1f1f;int dp(int x,int y){if (vis[x][y])return d[x][y];vis[x][y] = 1;if (x==y)return d[x][y]=1;if (x>y)return d[x][y] = inf;int& ans = d[x][y];ans = inf;for (int k=x;k<y;k++){ans = min(ans,dp(x,k) + dp(k+1,y));}if (b[x]==b[y]){ans = min(ans,dp(x,y-1));}return ans;}void print(){for (int i=1;i<=n;i++){for (int j=1;j<=n;j++){printf("%d ",d[i][j]);}cout << endl;}for (int i=0;i<=n;i++)printf("%d ",f[i]);cout << endl;}void init(){n = strlen(s+1);memset(d,inf,sizeof(d));memset(vis,0,sizeof(vis));dp(1,n);memset(f,inf,sizeof(f));f[0] = 0;for (int i=1;i<=n;i++){for (int j=1;j<=i;j++){f[i] = min(f[i],f[j-1] + d[j][i]);}if (s[i]==b[i]){f[i] = f[i-1];}}//print();printf("%d\n",f[n]);}int main() {//freopen("E:\\Code\\1.txt","r",stdin);while(scanf("%s%s",s+1,b+1)!=EOF){init();}return 0;}

0 0
原创粉丝点击