BZOJ5336:[TJOI2018]游园会——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5336
https://www.luogu.org/problemnew/show/P4590
小豆参加了NOI的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是N, O, I的字样。在会场上他收集到了K个奖章组成的串。兑奖规则是奖章串和兑奖串的最长公共子序列长度为小豆最后奖励的等级。现在已知兑奖串长度为N,并且在兑奖串上不会出现连续三个奖章为NOI,即奖章中不会出现子串NOI。现在小豆想知道各个奖励等级会对应多少个不同的合法兑奖串。
和BZOJ3864 & HDU4899:Hero meet devil大致一样,至于那个多出来的限制想怎么做就怎么做(包括我自己曾想过一个枚举的算法)。
一个很妙的做法是多记录当前的dp状态的末尾已经到达了"NOI"状态的第几位,然后转移即可。
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int p=1e9+;
const int N=;
const int M=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int s[N+];
int m,n,ans[N+],f[][<<N][],last[<<N],trans[<<N][],mp[][];
inline void readstring(){
int cnt=;char ch=;
while(ch<'A'||ch>'Z')ch=getchar();
while(ch>='A'&&ch<='Z'){
if(ch=='N')s[++cnt]=;if(ch=='O')s[++cnt]=;
if(ch=='I')s[++cnt]=;
ch=getchar();
}
}
void init(){
static int d[N+],g[N+];
for(int i=;i< <<n;i++){
if(i)last[i]=last[i^(i&-i)]+;
for(int j=;j<n;j++)d[j+]=d[j]+(bool)(i&(<<j));
for(int k=;k<;k++){
for(int j=;j<=n;j++){
g[j]=max(g[j-],d[j]);
if(s[j]==k)g[j]=max(g[j],d[j-]+);
}
trans[i][k]=;
for(int j=;j<n;j++)
if(g[j+]-g[j])trans[i][k]|=<<j;
}
}
}
int main(){
m=read(),n=read();
readstring();
init();
f[][][]=;int now=;
mp[][]=;mp[][]=;mp[][]=;mp[][]=;
mp[][]=;mp[][]=;mp[][]=;mp[][]=;
for(int i=;i<=m;i++){
memset(f[now],,sizeof(f[now]));
for(int j=;j< <<n;j++){
for(int l=;l<;l++){
for(int k=;k<;k++){
if(k==&&l==)continue;
(f[now][trans[j][k]][mp[l][k]]+=f[now^][j][l])%=p;
}
}
}
now^=;
}
for(int i=;i< <<n;i++)
for(int j=;j<;j++)
(ans[last[i]]+=f[now^][i][j])%=p;
for(int i=;i<=n;i++)printf("%d\n",(ans[i]+p)%p);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5336:[TJOI2018]游园会——题解的更多相关文章
- BZOJ5336 TJOI2018 party 【状压DP】*
BZOJ5336 TJOI2018 party Description 小豆参加了NOI的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是N, O, I的字样.在会场上他收集到了K个奖章组成 ...
- BZOJ5336: [TJOI2018]party
BZOJ5336: [TJOI2018]party https://lydsy.com/JudgeOnline/problem.php?id=5336 分析: 好题. 正常的思路是设\(f[i][j] ...
- [模板] dp套dp && bzoj5336: [TJOI2018]party
Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...
- 洛谷P4590 [TJOI2018]游园会(状压dp LCS)
题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...
- TJOI2018简要题解
Day1T1数学计算 按照时间轴建一棵线段树即可,复杂度为\(O(m \log m)\) #include <bits/stdc++.h> #define N 100005 #define ...
- luogu P4590 [TJOI2018]游园会 dp套dp
LINK:游园会 容易想到 设\(f[i][j][k][l]\)前i个字符 j表示状压的w个字符状态为j 长度<=k 匹配到了NOI的第l个位置的方案数. 不过只能得到30分. 考虑优化 其实优 ...
- TJOI2018 简要题解
数学计算 用线段树记录之前乘过的每一个数,作除法时把原本的乘数改成111即可. 代码: #include<bits/stdc++.h> #define lc (p<<1) #d ...
- DP 优化方法大杂烩 & 做题记录 I.
标 * 的是推荐阅读的部分 / 做的题目. 1. 动态 DP(DDP)算法简介 动态动态规划. 以 P4719 为例讲一讲 ddp: 1.1. 树剖解法 如果没有修改操作,那么可以设计出 DP 方案 ...
- DP套DP
DP套DP,就是将内层DP的结果作为外层DP的状态进行DP的方法. [BZOJ3864]Hero meet devil 对做LCS的DP数组差分后状压,预处理出转移数组,然后直接转移即可. tr[S] ...
随机推荐
- 「日常训练」Maximum Multiple(HDU-6298)
题意与分析 一开始以为是一条高深的数学题,跳过去了,后来查其他题目的代码的时候无意看到,一看emmmmmm 稍微思考一下就有了.\(1=\frac{1}{3}+\frac{1}{3}+\frac{1} ...
- Selenium(Python) ddt数据驱动
首先, 添加ddt模块: import unittestfrom time import sleep from ddt import ddt, data, unpack# 导入ddt模块from se ...
- Python安装教程最新版
Python安装教程最新版 目前Python官网已经更新到了最新版Python 3.7.1, 相比Python 2系列,它的兼容性不是太好, 不过应该会在不久的将来会全面解决.它的安装比较容易,具体步 ...
- vim基本命令笔记
两种模式 -编辑模式:可以进行正常的编辑操作 左下方显示 -- INSERT -- "在命令模式下输入 i 能够进入编辑模式" -命令模式:可以通过命令 左下方什么也不显示 &qu ...
- DeepLearning Intro - sigmoid and shallow NN
This is a series of Machine Learning summary note. I will combine the deep learning book with the de ...
- LeetCode - 167. Two Sum II - Input array is sorted - O(n) - ( C++ ) - 解题报告
1.题目大意 Given an array of integers that is already sorted in ascending order, find two numbers such t ...
- 基于spring-boot、spring-cloud的websocket服务器多点负载均衡改造
背景 为应对更多用户使用socket的场景,准备对存放websocket的服务器进行多点搭建并配置负载均衡. 问题 服务器上了多点负载均衡以后,基于socket的部分功能发生了有规律的失效,查看后台日 ...
- appcan打包后产生的问题总结
以appcan为基础的项目,最终需要打包后进行调试.在调试过程中,主要的样式问题在苹果手机上,下面将这些问题总结起来,以防下次再犯. 1:ios 7 以上的手机中,状态栏与内容重叠: 问题描述:在io ...
- Java语法基础课后作业
1.动手动脑 运行它EnumTest.java,分析运行结果 s和t分别引用的是SMALL和LARGE,枚举类型不是原始数据类型,s和u的赋值方式不同,但结果一样,列出它的所有值:SMALL,MEDI ...
- MyBatis传入参数为list、数组、map写法(转载)
MyBatis传入参数为list.数组.map写法 1.foreach简单介绍: foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合. foreach元素的属性主要有item ...