题目链接: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个字母顺序,循环使用。

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

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set> using namespace std; const int N=; const long long MOD=1e9+; char s[N];
struct Node {
char ch;
int pos;
Node(){
pos=-;
}
bool operator < (const Node &o) const {
return pos<o.pos;
}
}node[];
long long cnt[];
int main() {
for (int i=;i<;i++)
node[i].ch=char('a'+i);
int n,k;
scanf("%d %d",&n,&k);
scanf("%s",s);
int m=strlen(s);
for (int i=;i<m;i++) {
int id=s[i]-'a';
node[id].pos=i;
}
sort(node,node+k);
for (int i=m,cnt=;i<m+n;i++,cnt++) {
if (cnt>=k) cnt=;
s[i]=node[cnt].ch;
}
s[m+n]=;
//puts(s);
long long ret=;
memset(cnt,,sizeof cnt);
for (int i=;i<m+n;i++) {
long long tmp=ret;
int id=s[i]-'a';
ret=ret*-cnt[id];
ret+=MOD;
ret%=MOD;
while (ret<) ret+=MOD;
cnt[id]=tmp;
}
printf("%I64d\n",ret);
return ;
}

CF CROC 2016 Intellectual Inquiry的更多相关文章

  1. CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

    题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是 ...

  2. CROC 2016 - Elimination Round (Rated Unofficial Edition) E - Intellectual Inquiry dp

    E - Intellectual Inquiry 思路:我自己YY了一个算本质不同子序列的方法, 发现和网上都不一样. 我们从每个点出发向其后面第一个a, b, c, d ...连一条边,那么总的不同 ...

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

    E. Intellectual Inquiry 题目连接: http://www.codeforces.com/contest/655/problem/E Description After gett ...

  4. Codeforces 645E. Intellectual Inquiry(DP,贪心)

    Codeforces 645E. Intellectual Inquiry 题意:给定一串字符,由前k个小写拉丁字母组成,要求在该字符串后面补上n个字符(也从前k个小写拉丁字母里面选),使得最后得到的 ...

  5. CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 二分+拓扑排序

    D. Robot Rapping Results Report 题目连接: http://www.codeforces.com/contest/655/problem/D Description Wh ...

  6. codeforces 645 E. Intellectual Inquiry

    一个字符串,由前k个字母组成,长度为m + n,其中前m个字符已经确定,后面n个由你自由选择, 使得这个串的不同的子序列的个数最多,空串也算一个子序列. 1 <= m <= 10^6,0 ...

  7. CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT

    C. Binary Table 题目连接: http://codeforces.com/problemset/problem/662/C Description You are given a tab ...

  8. CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分

    题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值 ...

  9. codeforces 645E . Intellectual Inquiry

    题目链接 如果不考虑重复的元素, 那么我们可以很容易的发现, 长度为n的字符串它的子串数量是 $ 2^n $ . 我们设每个到位置i, 答案的数量为f[i]. 然后我们考虑重复的, 我们发现, 每加入 ...

随机推荐

  1. Java基础——运算符

    一.赋值运算符 在前面的学习中,用到最多的是什么呢?就是“=” .例如:int money=1000;   //储存本金 使用“=”将数值1000放入变量money的存储空间中.“=”称为赋值运算符. ...

  2. 3389: [Usaco2004 Dec]Cleaning Shifts安排值班

    3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 102  Solved: ...

  3. Python实现的异步代理爬虫及代理池

    使用python asyncio实现了一个异步代理池,根据规则爬取代理网站上的免费代理,在验证其有效后存入redis中,定期扩展代理的数量并检验池中代理的有效性,移除失效的代理.同时用aiohttp实 ...

  4. python rsa 加密解密 (编解码,base64编解码)

    最近有需求,需要研究一下RSA加密解密安全:在网上百度了一下例子文章,很少有文章介绍怎么保存.传输.打印加密后的文本信息,都是千篇一律的.直接在一个脚本,加密后的文本信息赋于变量,然后立马调用解密.仔 ...

  5. Android Studio开发遇到程序崩溃问题

    在用Android Studio开发过程中,经常遇到程序本身没有错误,但运行起来却总是挂掉,具体有如下几个解决方案: 1.将运行在真机上的app卸载,重新运行安装 2.在Build选项中有一个clea ...

  6. C#生成漂亮验证码完整代码类

    using System;using System.Web;using System.Drawing;using System.Security.Cryptography; namespace Dot ...

  7. iOS开发之控制器创建与加载(生命周期)

    1.如何创建一个控制器 控制器常见的创建方式有以下几种: (1)通过storyboard创建 (2)直接创建 MJViewController *mj = [[MJViewController all ...

  8. 无图无定位新版css步骤条兼容ie6+

    <ul class="ui-step list-unstyled"> <li class="step-item"><b class ...

  9. 百度api的使用

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  10. java封装的方法

    java封装是由Java是面向对象程序设计语言的性质决定的,面向对象程序设计语言的三大特性之一就是封装.封装其实就是包装的意思,从专业的角度来看,就是把对象的所有组成部分组合在一起,保护私有属性. 如 ...