CodeForces - 1337E Kaavi and Magic Spell(dp)
題目鏈接:點(diǎn)擊查看
題目大意:給出一個(gè)長(zhǎng)度為 n 的字符串 s 和一個(gè)長(zhǎng)度為 m 的字符串 t? ( n >= m ),現(xiàn)在有一個(gè)初始為空的字符串 a ,可以進(jìn)行最多 n 次操作,每次操作可以二選一:
問可以構(gòu)造出的 2^n 種情況里,有多少個(gè)字符串 a 是滿足前綴包含字符串 t 的
題目分析:因?yàn)榇鸢感枰∧?#xff0c;一般不是取模就是組合數(shù)學(xué),而這個(gè)題目實(shí)質(zhì)上是一個(gè)最優(yōu)性問題,那么就是 dp 跑不了了
因?yàn)?n 比較小,支持?n * n 的操作,以及可以開到二維 dp
就只能分析到這了。。因?yàn)槲业膁p不太好,所以接下來直接說題解吧
初始時(shí)我們將字符串 t 的長(zhǎng)度與字符串 s 的長(zhǎng)度視為相同,dp[ i ][ j ] 代表字符串 t 的區(qū)間 [ i , j ] 所代表的的子串的可達(dá)方案數(shù),那么答案顯然就是 dp[ 1 ][ m ] + dp[ 1 ][ m + 1 ] + ... + dp[ 1 ][ n ] 了
關(guān)于初始化,分兩種情況討論:
關(guān)于狀態(tài)轉(zhuǎn)移,也是分兩種情況討論,遍歷字符串 s ,枚舉 l 和 r 進(jìn)行轉(zhuǎn)移:
轉(zhuǎn)移方程應(yīng)該不難理解吧,如果需要比較的位置越界了,或者相等的話才進(jìn)行轉(zhuǎn)移,然后稍微注意一下枚舉的順序,就能做到 n?* n 轉(zhuǎn)移狀態(tài)了
代碼:
#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; }?
總結(jié)
以上是生活随笔為你收集整理的CodeForces - 1337E Kaavi and Magic Spell(dp)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 1335F R
- 下一篇: CodeForces - 1337D X