题意
现在给你n,k和长度为m的串
你需要构造一个长度为n+m的串,使得其中不同的子序列最多,输出数量。
题解:
构造题
假设我们构造出来了,我们怎么去统计呢?
dp[i]表示以i结尾的不同子序列数量,显然dp[i]=sigma(dp[j])+1,i!=j
观察可以知道其实dp[i]=前面所有不同子串数量-以i结尾的子串
统计知道了,我们怎么去构造呢?
贪心去构造就好了,我们可以简单的发现前面所有的不同的子串数量这个是相同的,我们取最少的以i结尾的那个字母就好了
这个显然就是最前面的那个字符,取最早出现的那个字符就好了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e6+7;
const int mod = 1e9+7;
string s;
int n,k,m,last[1005],dp[1005];
int main()
{
cin>>n>>k>>s;m=s.size();
for(int i=0;i<s.size();i++)
{
int x = s[i];
for(int j='a';j<'a'+k;j++)
{
if(x==j)continue;
dp[x]=(dp[x]+dp[j])%mod;
}
dp[x]=(dp[x]+1)%mod;
last[x]=i+1;
}
for(int i=1;i<=n;i++)
{
int x = 'a';
for(int j='a';j<'a'+k;j++)
if(last[j]<last[x])x=j;
for(int j='a';j<'a'+k;j++)
{
if(j==x)continue;
dp[x]=(dp[x]+dp[j])%mod;
}
dp[x]=(dp[x]+1)%mod;
last[x]=i+m;
}
long long ans = 0;
for(int i='a';i<'a'+k;i++)ans=(ans+dp[i])%mod;
cout<<(ans+1)%mod<<endl;
}