1. 程式人生 > >uva live 4394 String painter 區間dp

uva live 4394 String painter 區間dp

然而 ceil 表示 cout cstring als class 求解 post

// 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_popcountll typedef 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; }


uva live 4394 String painter 區間dp