[2020.12.6週日]Number of Subsequences
阿新 • • 發佈:2020-12-09
題意:給定一個含abc和?的序列,每一個?都可以取“a","b"或"c"。比如s="ac?b?c" 我們可以得到["acabac", "acabbc", "acabcc", "acbbac", "acbbbc", "acbbcc", "accbac", "accbbc", "accbcc"],求出abc子序列的數量。
題解:
我的思路:例如一個“a?c”這樣的子序列的貢獻是pow(3,num(?)-1),而所有的可以轉成abc的子序列的數量可求。
dp第一維0表示a,1表示ab,2表示abc;第二維表示其中?的個數。
第二種:到當前字母“a”,“b”,“c",這個字母的貢獻就是前面出現的?的數量的三次方.
注意點:
1.千萬不要覺得是一個很小的運算而不取mod,一道題目這個點可以w三次
2.如果是?裡面的程式碼,為了摒除干擾,應該倒著相加。
tag:dp
#include<bits/stdc++.h> using namespace std; const int maxn=5e6+10; typedef long long ll; const int mod=1e9+7; ll dp[3][4];//第一維0表示a,1表示ab,2表示abc;第二維表示其中?的個數 ll pre[maxn];//pre[i]=pow(3,i) void add(ll &a,ll b){a=(a+b)%mod;} int main() { int n;cin>>n; string s;cin>>s; pre[0]=1;ll cnt=0;//cnt=num(?) for(int i=0;i<n;i++) { if(s[i]=='a')add(dp[0][0],1); else if(s[i]=='b') add(dp[1][0],dp[0][0]),add(dp[1][1],dp[0][1]); else if(s[i]=='c') add(dp[2][0],dp[1][0]),add(dp[2][1],dp[1][1]),add(dp[2][2],dp[1][2]); else { add(dp[2][3],dp[1][2]);add(dp[2][2],dp[1][1]);add(dp[2][1],dp[1][0]); add(dp[1][2],dp[0][1]);add(dp[1][1],dp[0][0]); add(dp[0][1],1); add(cnt,1); } pre[i+1]=3*pre[i]%mod; } ll ans=0; for(int i=0;i<=3;i++) { add(ans,pre[cnt-i]*dp[2][i]%mod); } cout<<ans<<endl; }
我覺得自己的程式碼寫得不夠優美,第二個維度可刪,參考部落格
#include<bits/stdc++.h> using namespace std; const int maxn=5e5+10; typedef long long ll; const int mod=1e9+7; int main() { int n;cin>>n; string s;cin>>s; ll a=0,ab=0,abc=0,cnt=1; for(int i=0;i<n;i++) { if(s[i]=='a')a=(a+cnt)%mod; else if(s[i]=='b') ab=(ab+a)%mod; else if(s[i]=='c') abc=(abc+ab)%mod; else { abc=(abc*3+ab)%mod; ab=(ab*3+a)%mod; a=(a*3+cnt)%mod; cnt=cnt*3%mod; } } cout<<abc%mod<<endl; }