CF CROC 2016 Intellectual Inquiry

题目链接:http://codeforces.com/contest/655/problem/E

大意是Bessie只会英文字母表中的前k种字母,现在有一个长度为m+n的字母序列,Bessie已经知道了前m个字符,问如何填充剩下的n个字符,使得整个序列的不同子序列数目最大。当然所有字母都得是Bessie会的前k个字母。

两个月前比赛的时候做的,是一道不错的题。

 

关于子序列个数的计算

令dp[i]表示前i个数字组成的序列中子序列的个数,

则对于第i个数字a[i]来说,dp[i]来源于两种情况的转化:

序列中前一个数字为a[i],记这种情况为s1以及前一个数字不为a[i],计这种情况为s2。

dp[i]=s1+s2*2=2*dp[i-1]-s1

可以这么理解,首先之前的子序列个数是dp[i-1],这些子序列直接都加一个a[i],一定是可以的。这只是新答案中以a[i]为结尾的情况,那么不以a[i]为结尾的情况,直接就是继承自原来的s2。

所以可以看出要使得dp值尽量大,就要让每一次因为重复需要减去的s1值尽可能小,也就是要让a[i]距离上一次出现a[i]尽可能地远。

根据前m个字符信息,计算可以使用的k个字母的最后出现的位置,根据这个来进行排序,使得最后出现的位置越小的字母排在越前面。

对于剩下的n个需要填充的字符,直接按照排出来的k个字母顺序,循环使用。

最后按照上述子序列计算方式来进行计算。

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <math.h>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11 #include <set>
12 
13 using namespace std;
14 
15 
16 const int N=2234567;
17 
18 const long long MOD=1e9+7;
19 
20 char s[N];
21 struct Node {
22     char ch;
23     int pos;
24     Node(){
25         pos=-1;
26     }
27     bool operator < (const Node &o) const {
28         return pos<o.pos;
29     }
30 }node[30];
31 long long cnt[30];
32 int main() {
33     for (int i=0;i<26;i++)
34         node[i].ch=char('a'+i);
35     int n,k;
36     scanf("%d %d",&n,&k);
37     scanf("%s",s);
38     int m=strlen(s);
39     for (int i=0;i<m;i++) {
40         int id=s[i]-'a';
41         node[id].pos=i;
42     }
43     sort(node,node+k);
44     for (int i=m,cnt=0;i<m+n;i++,cnt++) {
45         if (cnt>=k) cnt=0;
46         s[i]=node[cnt].ch;
47     }
48     s[m+n]=0;
49     //puts(s);
50     long long ret=1;
51     memset(cnt,0,sizeof cnt);
52     for (int i=0;i<m+n;i++) {
53         long long tmp=ret;
54         int id=s[i]-'a';
55         ret=ret*2-cnt[id];
56         ret+=MOD;
57         ret%=MOD;
58         while (ret<0) ret+=MOD;
59         cnt[id]=tmp;
60     }
61     printf("%I64d\n",ret);
62     return 0;
63 }
View Code

 

posted @ 2016-05-06 14:54  活在夢裡  阅读(207)  评论(0编辑  收藏  举报