日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVALive 4394 String painter

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVALive 4394 String painter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  題目大意:有兩個字符串A,B,一次刷可以把A串一段刷成同一個字母,問至少要刷幾次才能把A串變成B串。串長≤100。

  本來以為是個很簡單的區間DP,后來發現直接區間DP是不行的,這玩意有后效性:刷完一整塊之后這一塊就變了。

  對于這種問題不如干脆利落一點,直接把 f[ ][ ]設成將空串(即不需要考慮A與B的相同)刷成B串的最小次數。

  這個時候的轉移方程就是:

for(int i=1;i<=n;++i)f[i][i]=1;for(int len=1;len<n;++len)for(int i=1;i+len<=n;++i){int j=i+len;f[i][j]=f[i+1][j]+1;for(int k=i+1;k<=j;++k)if(B[i]==B[k])f[i][j]=min(f[i][j],f[i+1][k]+f[k+1][j]);}

  這個轉移方程是很巧妙的。

  首先賦值最壞情況,作為最大值,然后枚舉k,進行更新。

  轉移方程的思想是:如果在B串中,i和k是一樣的,就可以劃分區間進行更新。

  結論:在涂色的時候,區間的一個端點,一定可以作為第一個涂色。

  證明:區間涂色有兩種方法:分成左右 / 先整個涂一遍再在里面涂。

  分成左右是子問題,先整個涂的話就可以先選擇這個端點涂。

  所以在轉移時,如果i和k是一樣的,則可以有f[i][k]=f[i+1][k],只需要在涂k的時候把整個區間涂上就可以了。

  同樣可以用上面的子問題思考方式證明。

  這樣就把"空串變B串"解決了。但是我們是要把A串變B串,答案還需要統計一遍。

  設g[i]表示A串從1到i全部被涂成B的最小步數,用f來更新g。

  這個時候轉移方程就是這樣:

g[1]=A[1]==B[1]?0:1;for(int i=2;i<=n;++i){if(A[i]==B[i]){g[i]=g[i-1];continue;}g[i]=f[1][i];for(int j=1;j<i;++j)g[i]=min(g[i],g[j]+f[j+1][i]);}

  這個轉移也是比較有意思的,這里就不做分析了。

  對于這種顯然只能用DP來做的、一般的轉移又有后效性的題,不妨狀態設大氣一點,直接忽略后效性帶來的影響,再變換方式統計答案。

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <cstring> #include <queue> #include <complex> #include <stack> #define LL long long int #define dob double #define FILE "4394" using namespace std;const int N = 110; int n,f[N][N],g[N]; char A[N],B[N];inline int gi(){int x=0,res=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*res; }inline void solve(){n=strlen(A+1);for(int i=1;i<=n;++i)f[i][i]=1;for(int len=1;len<n;++len)for(int i=1;i+len<=n;++i){int j=i+len;f[i][j]=f[i+1][j]+1;for(int k=i+1;k<=j;++k)if(B[i]==B[k])f[i][j]=min(f[i][j],f[i+1][k]+f[k+1][j]);}g[1]=A[1]==B[1]?0:1;for(int i=2;i<=n;++i){if(A[i]==B[i]){g[i]=g[i-1];continue;}g[i]=f[1][i];for(int j=1;j<i;++j)g[i]=min(g[i],g[j]+f[j+1][i]);}printf("%d\n",g[n]); }int main(){freopen(FILE".in","r",stdin);freopen(FILE".out","w",stdout);while(~scanf("%s%s",A+1,B+1))solve();fclose(stdin);fclose(stdout);return 0; } String painter

?

轉載于:https://www.cnblogs.com/fenghaoran/p/7671155.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的UVALive 4394 String painter的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。