动态规划subsequence 1
Posted osea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划subsequence 1相关的知识,希望对你有一定的参考价值。
题意:
两个串,s t,求s的所有子串中大于 t 的数目
题解:
dp[i][j] 表示 s的前i个,匹配 t 的前 j 个的种类数,
那么 if(s[i] == t[j])
dp[i][j] = dp[i -1][j] + dp[i - 1][j - 1];
else
dp[i][j] = dp[i - 1][j];
对于长度大于 t 的没有前导0的都符合,那么就看长度等于t的就可以了,
当匹配到 i, j 的时候,if(s[i] > t[j]) 那么该贡献为:
前面匹配j-1的种类数*后面随便选len2-j个,即当前的贡献就为dp[i - 1][j - 1] * C[len1 - i][len2 - j]。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N = 3005; 5 const ll mod = 998244353 ; 6 char s[N],t[N]; 7 ll C[N][N]; 8 ll dp[N][N]; 9 int main() 10 11 //打表杨辉三角 12 C[0][0] = 1 ; 13 C[1][0] = C[1][1] = 1 ; 14 for(int i=2;i<=3000;i++) 15 C[i][0] = 1 ; 16 for(int j=1;j<=i;j++) 17 C[i][j] = C[i-1][j-1] + C[i-1][j] ; 18 if(C[i][j]>=mod) C[i][j] -= mod ; 19 20 21 22 int T,n,m; 23 for( scanf("%d",&T) ; T ; T-- ) 24 scanf("%d%d",&n,&m); 25 scanf("%s%s",s+1,t+1); 26 27 for(int i=0;i<=n;i++) 28 dp[i][0] = 1 ; 29 30 //计算长度相同时,某一位置比t的位置大,对答案的贡献 31 ll ans = 0 ; 32 for(int i=1;i<=n;i++) 33 for(int j=1;j<=min(i,m);j++) 34 dp[i][j] = dp[i-1][j] ; 35 if( s[i] == t[j] ) 36 dp[i][j] = (dp[i][j] + dp[i-1][j-1]) % mod ; 37 38 else if( s[i] > t[j] ) 39 ans = (ans + (ll)dp[i-1][j-1] * C[n-i][m-j]) %mod ; 40 41 42 43 //计算长度大于t串长度时,对答案的贡献 44 for(int i=1;i<=n;i++) 45 if( s[i] ==‘0‘ ) continue ; 46 for(int j=m;j<=n-i;j++) 47 ans = (ans + C[n-i][j])%mod ; 48 49 50 printf("%lld\n",ans); 51 52 return 0; 53
以上是关于动态规划subsequence 1的主要内容,如果未能解决你的问题,请参考以下文章
动态规划之115 Distinct Subsequences
POJ 1458 Common Subsequence (动态规划)
1007. Maximum Subsequence Sum (25) 动态规划
[动态规划] leetcode 115 Distinct Subsequences