本质上升序列(蓝桥杯2020国赛)
原题链接
考察:线性dp
思路:
其实递推方程超简单,只是我蠢.
if(s[i]>s[j]) dp[i]+=dp[j]
else if(s[i]==s[j]) dp[i]-=dp[j];
如果s[i]==s[j],那么dp[i]从前面<s[i]获得的子序列都要减去,因为与s[j]构成了重复.
Code
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
const int N = 210;
string s;
int f[N];
int solve()
{
for(int i=0;i<4;i++)
{
string t;
cin>>t;
s+=t;
}
int len = s.size();
for(int i=0;i<len;i++)
{
f[i] = 1;
for(int j=0;j<i;j++)
if(s[i]>s[j]) f[i]+=f[j];
else if(s[i]==s[j]) f[i]-=f[j];
}
int ans = 0;
for(int i=0;i<len;i++) ans+=f[i];
return ans;
}
int main()
{
printf("%d\n",solve());
return 0;
}