字符串中子序列出现次数
作者:互联网
题意,给一个字符串,求子序列“cwbc”出现的次数
分析:
dp,滚动数组
令 f[i][j],(j = 1,2,3,4) 表示前 i 个字符中,匹配了字符串”cwbc” 的前多少位,那么有转移方程:
f[i][1] = (f[i−1][1] + (s[i] ==′ c′)) % Mod
f[i][2] = (f[i−1][2] + (s[i] ==′ w′)∗f[i−1][1]) % Mod
f[i][3] = (f[i−1][3] + (s[i] ==′ b′)∗f[i−1][2]) % Mod
f[i][4] = (f[i−1][4] + (s[i] ==′ c′)∗f[i−1][3]) % Mod
内存超标。使用滚动数组优化开销:
f[1] = (f[1] + (s[i] ==′ c′)) % Mod
f[2] = (f[2] + (s[i] ==′ w′)∗f[1]) % Mod
f[3] = (f[3] + (s[i] ==′ b′)∗f[2]) % Mod
f[4] = (f[4] + (s[i] ==′ c′)∗f[3]) % Mod
代码中动规的第二维正着来反着来都没区别,因为互有关联的21,32,43都是二者只可能有一个执行的,而14虽然都有可能执行,但互不影响
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=1<<30; 4 typedef long long ll; 5 const double pi=acos(-1); 6 const int mod=2000120420010122; 7 const int maxn=2e5+7; 8 ll dp[5]; 9 int main(){ 10 string s; 11 while(cin>>s){ 12 memset(dp,0,sizeof(dp)); 13 for(int i=0;i<s.length();i++){ 14 s[i]=tolower(s[i]); 15 dp[4]=(dp[4]+(s[i]=='c')*dp[3])%mod; 16 dp[3]=(dp[3]+(s[i]=='b')*dp[2])%mod; 17 dp[2]=(dp[2]+(s[i]=='w')*dp[1])%mod; 18 dp[1]=(dp[1]+(s[i]=='c'))%mod; 19 } 20 cout<<dp[4]<<endl; 21 } 22 return 0; 23 }
标签:滚动,int,cwbc,序列,中子,字符串,dp,Mod 来源: https://www.cnblogs.com/qingjiuling/p/10429032.html