BZOJ5336: [TJOI2018]party
BZOJ5336: [TJOI2018]party
https://lydsy.com/JudgeOnline/problem.php?id=5336
分析:
- 好题。
- 正常的思路是设\(f[i][j][0/1/2]\)表示前\(i\)个位置,与奖章串的\(lcs\)状态为\(j\),匹配到\(NOI\)的第几位,然后转移。
- 那么问题是这个\(lcs\)的状态如何存储,打个表发现这个状态数很少,实际上也是这样的,因为在匹配\(lcs\)的过程中,相邻两位\(dp\)值最多差\(1\),状态数\(2^k\)。
- 然后就做完了,预处理出来每个状态能转移到的状态即可。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 1050
#define mod 1000000007
char w[N];
int n,K;
typedef long long ll;
int tr[1<<15][3],sf[N],sg[N],cnt[1<<15];
ll f[2][1<<15][3],ans[N];
inline void upd(ll &x,ll y) {
x=x+y; if(x>=mod) x-=mod;
}
int main() {
scanf("%d%d%s",&n,&K,w+1);
int i,mask=(1<<K)-1,s;
for(s=0;s<=mask;s++) {
for(i=1;i<=K;i++) {
sf[i]=sf[i-1]+((s>>(i-1))&1);
}
for(i=1;i<=K;i++) {
if(w[i]=='N') sg[i]=sf[i-1]+1;
else sg[i]=max(sg[i-1],sf[i]);
tr[s][0]|=(sg[i]-sg[i-1])*(1<<(i-1));
}
for(i=1;i<=K;i++) {
if(w[i]=='O') sg[i]=sf[i-1]+1;
else sg[i]=max(sg[i-1],sf[i]);
tr[s][1]|=(sg[i]-sg[i-1])*(1<<(i-1));
}
for(i=1;i<=K;i++) {
if(w[i]=='I') sg[i]=sf[i-1]+1;
else sg[i]=max(sg[i-1],sf[i]);
tr[s][2]|=(sg[i]-sg[i-1])*(1<<(i-1));
}
}
f[0][0][0]=1;
for(i=0;i<n;i++) {
int i0=i&1,i1=(i+1)&1;
for(s=0;s<=mask;s++) {
//O/I->N
upd(f[i1][tr[s][0]][1],f[i0][s][0]);
//O/I->O
upd(f[i1][tr[s][1]][0],f[i0][s][0]);
//O/I->I
upd(f[i1][tr[s][2]][0],f[i0][s][0]);
//N->N
upd(f[i1][tr[s][0]][1],f[i0][s][1]);
//N->O
upd(f[i1][tr[s][1]][2],f[i0][s][1]);
//N->I
upd(f[i1][tr[s][2]][0],f[i0][s][1]);
//NO->N
upd(f[i1][tr[s][0]][1],f[i0][s][2]);
//NO->O
upd(f[i1][tr[s][1]][0],f[i0][s][2]);
}
memset(f[i0],0,sizeof(f[i0]));
}
for(i=0;i<=mask;i++) cnt[i]=cnt[i>>1]+(i&1);
for(s=0;s<=mask;s++) for(i=0;i<3;i++) upd(ans[cnt[s]],f[n&1][s][i]);
for(i=0;i<=K;i++) printf("%lld\n",ans[i]);
}
BZOJ5336: [TJOI2018]party的更多相关文章
- BZOJ5336 TJOI2018 party 【状压DP】*
BZOJ5336 TJOI2018 party Description 小豆参加了NOI的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是N, O, I的字样.在会场上他收集到了K个奖章组成 ...
- [模板] dp套dp && bzoj5336: [TJOI2018]party
Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...
- DP套DP
DP套DP,就是将内层DP的结果作为外层DP的状态进行DP的方法. [BZOJ3864]Hero meet devil 对做LCS的DP数组差分后状压,预处理出转移数组,然后直接转移即可. tr[S] ...
- 【BZOJ5336】[TJOI2018]party(动态规划)
[BZOJ5336][TJOI2018]party(动态规划) 题面 BZOJ 洛谷 题解 这题好神仙啊... 考虑普通的\(LCS\)的\(dp\),\(f[i][j]=\max\{f[i-1][j ...
- BZOJ5336:[TJOI2018]游园会——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5336 https://www.luogu.org/problemnew/show/P4590 小豆 ...
- bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338 题面: 5338: [TJOI2018]xor Time Limit: 30 Sec ...
- 洛谷P4590 [TJOI2018]游园会(状压dp LCS)
题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...
- 【BZOJ5339】[TJOI2018]教科书般的亵渎(斯特林数)
[BZOJ5339][TJOI2018]教科书般的亵渎(斯特林数) 题面 BZOJ 洛谷 题解 显然交亵渎的次数是\(m+1\). 那么这题的本质就是让你求\(\sum_{i=1}^n i^{m+1} ...
- 【BZOJ5337】[TJOI2018]str(动态规划,哈希)
[BZOJ5337][TJOI2018]str(动态规划,哈希) 题面 BZOJ 洛谷 题解 就很呆... 显然按层\(dp\),如果能够匹配上就进行转移,直接哈希判断是否能够匹配就好了... #in ...
随机推荐
- iOS 优化界面流畅度的探讨
界面流畅度 大都跟list scrollView有紧密关联 流畅的视觉:就是如丝般顺滑 不流畅视觉:”卡顿”,”抖动”,”迟顿感” 以上两种状态的描述 都是基于主观感觉,对于开发者来说 确实应该有一个 ...
- $Android自定义控件风格的方法
EditText在获取焦点后默认的边框都是黄色的,这可能和我在开发的应用的主题颜色不匹配,那怎么办呢?——用自定义的控件风格,比如说我想让EditText在获取焦点时候边框变成蓝色的,而失去焦点后边框 ...
- qq 微信 微博 第三方分享
<html> <head> <meta charset="utf-8"> <meta name="viewport" ...
- Android 电容屏驱动
Android 电容屏(一):电容屏基本原理篇 Android 电容屏(二):驱动调试之基本概念篇 Android 电容屏(三):驱动调试之驱动程序分析篇
- yield 表达式形式的应用
import random foods=['banana','apple','peach','grape','pear'] def deco(func): def wrapper(*args,**kw ...
- PHP面试题汇总一
1.表单中 get与post提交方法的区别? 答:get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据,可以通过表单提交大量信息. 2.session与cookie的区别? 答 ...
- iOS下的WiFi开发
iOS下Wi-Fi开发需要添加依赖库SystemConfiguration.framework,在需要使用Wi-Fi信息的控制器下引入头文件#import <SystemConfiguratio ...
- Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间
一看就知道 可以LCA判断做 也可以树链剖分拿头暴力 然而快速读入和线段树维护区间会T70 于是只能LCA? 线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组 这个题 ...
- QT QDialog如何弹出一个子窗口
1. 假设已有一个QDialog的父窗口, 想弹出的子窗口为自己实现的myDialog : QDialog. myDialog 设计和平常的QDialog一样, childDialog : publi ...
- centos6.5 安装JDK
今天在自己的centos机子上安装jdk,发现以前的教程都比较旧了,很多东西都过时了.今天把自己安装的感受写一下. 判断是否安装 首先,我们得判断机子上是不是安装了jdk,好多人推荐使用java -v ...