字符串中子序列出现次数

题目链接

题意,给一个字符串,求子序列“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 }

猜你喜欢

转载自www.cnblogs.com/qingjiuling/p/10429032.html