本质上升序列(蓝桥杯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;
}
posted @ 2021-06-04 12:11  acmloser  阅读(328)  评论(0编辑  收藏  举报