BZOJ5336 TJOI2018 party


Description

小豆参加了NOI的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是N, O, I的字样。在会场上他收集到了K个奖章组成的串。

兑奖规则是奖章串和兑奖串的最长公共子序列长度为小豆最后奖励的等级。

现在已知兑奖串长度为N,并且在兑奖串上不会出现连续三个奖章为NOI,即奖章中不会出现子串NOI。

现在小豆想知道各个奖励等级会对应多少个不同的合法兑奖串。

Input

第一行两个数,N,K分别代表兑奖串的长度,小豆收集的奖章串的长度。

第二行一共K个字符,表示小豆得到奖章串。

N<=1000 & K<=15

Output

一共K+1行,第i行表示小豆最后奖励等级为i-1的不同的合法兑奖串的个数,可能这个数会很大,结果对10^9 + 7取模。

Sample Input

3 2

NO

Sample Output

1

19

6

提示

最长公共子序列长度0的串有:III;

最长公共子序列长度2的串有:NON, NNO, NOO, ONO,INO, NIO;

除去NOI,余下的19(26-6-1)种为最长公共子序列长度为1。


我们发先在对lsm进行计算的时候相邻两个DP值的差最多是一,所以我们借此进行状态构造。把一个dp值差分后的01串作为状态,然后对这个状态进行DP,因为我们需要考虑的特殊情况只有NOI,所以添加一维记一下状态就好了


#include<bits/stdc++.h>
using namespace std;
#define K 20
#define N 1010
#define S (1<<16)
#define Mod 1000000007
int n,k,bit[K],ans[K]={0};
int now[K]={0},res[K]={0},a[K];
int T[S][3]={0};
int dp[2][3][S]={0},ind=0,frm=1;
/*
dp数组中第二维
0->没有特殊限制
1->末尾是N
2->末尾是NO
*/
/*
N->0
O->1
I->2
*/
void add(int &x,int y){x=(x+y)%Mod;}
int countsiz(int s){int cnt=0;while(s)cnt++,s-=s&-s;return cnt;}
int main(){
scanf("%d%d",&n,&k);
getchar();
for(int i=1;i<=k;i++){
char c;scanf("%c",&c);
if(c=='N')a[i]=0;
if(c=='O')a[i]=1;
if(c=='I')a[i]=2;
}
bit[1]=1;for(int i=2;i<=k;i++)bit[i]=bit[i-1]<<1;
int up=(1<<k)-1;
for(int s=0;s<=up;s++){
for(int i=1;i<=k;i++)
now[i]=now[i-1]+(bool)(s&bit[i]);
for(int typ=0;typ<3;typ++){
for(int i=1;i<=k;i++)
if(a[i]==typ)res[i]=now[i-1]+1;
else res[i]=max(res[i-1],now[i]);
for(int i=1;i<=k;i++)T[s][typ]|=bit[i]*(res[i]-res[i-1]);
}
}
dp[ind][0][0]=1;
for(int i=1;i<=n;i++){
ind^=1;frm^=1;
memset(dp[ind],0,sizeof(dp[ind]));
for(int s=0;s<=up;s++){
//没有限制->没有限制(当前出现O或I)
add(dp[ind][0][T[s][1]],dp[frm][0][s]);
add(dp[ind][0][T[s][2]],dp[frm][0][s]);
//没有限制->限制1(当前出现N)
add(dp[ind][1][T[s][0]],dp[frm][0][s]);
//限制1->没有限制(当前出现I)
add(dp[ind][0][T[s][2]],dp[frm][1][s]);
//限制1->限制1(当前出现N)
add(dp[ind][1][T[s][0]],dp[frm][1][s]);
//限制1->限制2(当前出现O)
add(dp[ind][2][T[s][1]],dp[frm][1][s]);
//限制2->没有限制(当前出现O)
add(dp[ind][0][T[s][1]],dp[frm][2][s]);
//限制2->限制1(当前出现N)
add(dp[ind][1][T[s][0]],dp[frm][2][s]);
}
}
for(int s=0;s<=up;s++)
for(int i=0;i<3;i++)
add(ans[countsiz(s)],dp[ind][i][s]);
for(int i=0;i<=k;i++)printf("%d\n",ans[i]);
return 0;
}


BZOJ5336 TJOI2018 party 【状压DP】*的更多相关文章

  1. 洛谷P4590 [TJOI2018]游园会(状压dp LCS)

    题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...

  2. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  3. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  4. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  5. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  6. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  7. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  8. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

  9. 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP

    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...

  10. 【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP

    [BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M< ...

随机推荐

  1. 医疗数据库 Caché 开发笔记

    目前所知的 Caché 是应用在医院信息系统(即 HIS),据说在欧美医疗卫生行业,Caché 占了 70% 的市场份额.国内的东华软件就是采用 Caché 数据库,东华软件在国内医院市场占有率大致为 ...

  2. Java并发之synchronized深入

    一句话总结synchronized: JVM会自动通过使用monitor来加锁和解锁,保证了同时只有一个线程可以执行指定代码,从而保证了线程安全,同时具有可重入和不可中断的性质. 一.synchron ...

  3. arm中的几个公式的比较

    串口 UART0.UBRDIVO=0X4d; 设置波特率 12000000/9600/16 -1=77化为16进制就是4dADC AD converter freq =50MHZ/(49+1) =1M ...

  4. 搭建etcd集群

    一 介绍 etcd 高可用一致性键值存储系统,使用Raft一直算法处理日志复制以保证数据一致性.主要在搭建kubernates时关注到etcd来研究部署etcd.使用golang语言编写,和zooke ...

  5. 括号匹配——nyoj2

    感觉自己的逻辑就像屎一样,这么简单的题目写了2个小时,以后写题还是要在纸上先列好提纲,不然如果你直接上机,遇到n多个bug的时候,容易迷失自我,去拆东补西的修bug而忽视了整片代码的逻辑的正确性. 在 ...

  6. Ubuntu 下Python 环境问题

    问题描述: 原先使用Anaconda环境,若卸载后仍不能恢复到系统默认的Python环境. 解决方案: shell 寻找缓存路径,python的扩展/home/tom/anaconda/bin/pyt ...

  7. restframework api(基础2)

    一 socket简介 1 最简单的socket #################server import socket ip_port = ('127.0.0.1',9997) sk = sock ...

  8. shiro的三大功能

    1.提供的功能

  9. iOS 可能用到的三方框架

    1.MWPhotoBrowser 第三方图片浏览器 https://github.com/mwaterfall/MWPhotoBrowser 2.SlackTextViewController  强大 ...

  10. OC-NSArray

    一.认识数组 oc中可以把NSObject对象的子类放到数组这个集合中,但是int.float.double等基础数据类型需要先进行转换才可以存入数组. oc中数组以NS开头,其中分为可变数组和不可变 ...