CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp

题意

现在给你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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值