题意:
就是给你一个字符串,问你字符串cwbc在这个字符串中作为子序列出现了多少次。
思考:
之前做过这样的,就是去dp,dp[i][j]代表走到第i位,匹配到第j的方案数,如果a[i]==b[j],那么dp[i][j] +=dp[i-1][j]+dp[i-1][j-1],也就是可以从上一位的j-1过来,当然也可以不动。所以最后dp[n][m]就是答案。当然了这个可以优化为一维的,发现每次都是dp[i]从dp[i-1]转移过来,所以直接去掉第一维,只留第二维,就变成了滚动数组即可。
代码:
二维:
int T,n,m,k;
int dp[N][10];
signed main()
{
IOS;
string a,b;
while(cin>>a)
{
cin>>a;
for(int i=0;i<a.size();i++) if(a[i]>='A'&&a[i]<='Z') a[i] += 32;
b = "cwbc";
n = a.size(),m = b.size();
a = " "+a,b = " "+b;
for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) dp[i][j] = 0;
for(int i=0;i<=n;i++) dp[i][0] = 1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j] = dp[i-1][j]%mod;
if(a[i]==b[j]) dp[i][j] = (dp[i-1][j]+dp[i-1][j-1])%mod;
}
}
cout<<dp[n][m]%mod;
}
return 0;
}
优化到一维:
int T,n,m,k;
int dp[10];
signed main()
{
IOS;
string a,b;
while(cin>>a)
{
for(int i=0;i<a.size();i++) if(a[i]>='A'&&a[i]<='Z') a[i] += 32;
b = "cwbc";
n = a.size(),m = b.size();
a = " "+a,b = " "+b;
for(int i=0;i<=m;i++) dp[i] = 0;
dp[0] = 1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(a[i]==b[j]) dp[j] = (dp[j]+dp[j-1])%mod;
}
cout<<dp[m]%mod<<"\n";
}
return 0;
}
总结:
多多思考,想好。