这题一开始是想的dp,但是不知道本质不同该怎么处理。
后来经过队友的讲解,我们可以设 d p [ i ] dp[i] dp[i]为以i结尾有多少个本质不同上升子序列,我们手玩一下样例可以发现,对于k<j<i,若s[i]>s[j],那么s[j]>s[k]也会包含在s[j]里面,根据这个,我们可以贪心地想,如果s[i]>s[j]&&s[i]>s[k]&&s[j]==s[k],我们只需要统计s[j]的答案就可以了,因为字符在后面,能统计的字符更多。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<sstream>
#include<queue>
#include<list>
#include<stack>
#include<bitset>
#include<cmath>
#include<map>
#include<functional>
#define int long long
#define IO ios::sync_with_stdio(false)
using namespace std;
int n,dp[300];//以i结尾有多少个本质不同子序列
bool vis[5005];
char s[2005];
signed main()
{
IO;
cin>>s+1;
int len=strlen(s+1);
for(int i=1;i<=len;i++)
{
dp[i]=1;
}
for(int i=1;i<=len;i++)
{
memset(vis,false,sizeof(vis));
for(int j=i-1;j>=1;j--)
{
if(s[i]>s[j]&&!vis[s[j]])
{
vis[s[j]]=true;
dp[i]+=dp[j];
}
}
}
int ans=0;
memset(vis,false,sizeof(vis));
for(int i=len;i>=1;i--)
{
if(!vis[s[i]])
{
vis[s[i]]=true;
ans+=dp[i];
}
}
cout<<ans;
}