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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CodeForces - 1337E Kaavi and Magic Spell(dp)

發布時間:2024/4/11 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1337E Kaavi and Magic Spell(dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個長度為 n 的字符串 s 和一個長度為 m 的字符串 t? ( n >= m ),現在有一個初始為空的字符串 a ,可以進行最多 n 次操作,每次操作可以二選一:

  • 刪除掉 s 最前面的字符,將這個字符加到 a 前面
  • 刪除掉 s 最前面的字符,將這個字符加到 a 后面
  • 問可以構造出的 2^n 種情況里,有多少個字符串 a 是滿足前綴包含字符串 t 的

    題目分析:因為答案需要取模,一般不是取模就是組合數學,而這個題目實質上是一個最優性問題,那么就是 dp 跑不了了

    因為 n 比較小,支持?n * n 的操作,以及可以開到二維 dp

    就只能分析到這了。。因為我的dp不太好,所以接下來直接說題解吧

    初始時我們將字符串 t 的長度與字符串 s 的長度視為相同,dp[ i ][ j ] 代表字符串 t 的區間 [ i , j ] 所代表的的子串的可達方案數,那么答案顯然就是 dp[ 1 ][ m ] + dp[ 1 ][ m + 1 ] + ... + dp[ 1 ][ n ] 了

    關于初始化,分兩種情況討論:

  • 如果 t[ i ] == s[ 1 ] ,樣例也提示了,第一次操作有兩種方法,效果都是一樣的,所以 dp[ i ][ i ] = 2?
  • 如果 i >m ,說明這個位置無論放什么字符,也不會影響到字符串 a 的前綴,所以同上 dp[ i ][ i ] = 2
  • 關于狀態轉移,也是分兩種情況討論,遍歷字符串 s ,枚舉 l 和 r 進行轉移:

  • 如果 l?> m 或?s[ i ] == t[ l ] ,那么 dp[ l ][ r ] += dp[ l + 1 ][ r ] ,也就是將 s[ i ] 添加到字符串 a 的前面
  • 如果 r > m 或 s[ i ] == t[ r ] ,那么 dp[ l ][ r ] += dp[ l ][ r - 1 ] ,也就是將 s[ i ] 添加到字符串 a 的后面
  • 轉移方程應該不難理解吧,如果需要比較的位置越界了,或者相等的話才進行轉移,然后稍微注意一下枚舉的順序,就能做到 n?* n 轉移狀態了

    代碼:

    #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=3e3+100;const int mod=998244353;LL dp[N][N];char s[N],t[N];int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);scanf("%s%s",s+1,t+1);int n=strlen(s+1),m=strlen(t+1);for(int i=1;i<=m;i++)if(t[i]==s[1])dp[i][i]=2;for(int i=m+1;i<=n;i++)dp[i][i]=2;for(int len=2;len<=n;len++){char ch=s[len];for(int l=1;l+len-1<=n;l++){int r=l+len-1;if(l>m||ch==t[l])//加在前面 dp[l][r]=(dp[l][r]+dp[l+1][r])%mod;if(r>m||ch==t[r])//加在后面 dp[l][r]=(dp[l][r]+dp[l][r-1])%mod;}}LL ans=0;for(int i=m;i<=n;i++)ans=(ans+dp[1][i])%mod;printf("%lld\n",ans);return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的CodeForces - 1337E Kaavi and Magic Spell(dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

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