洛谷P4590 [TJOI2018]游园会(状压dp LCS)
题意
Sol
这个题可能是TJOI2018唯一的非模板题了吧。。
考虑LCS的转移方程,
\]
也就是说我们如果知道了前一个列向量\(f[i - 1]\)以及\(A_i, B_j\)我们就可以转移了
那么可以暴力dp,\(f[i][sta][0/1/2]\)表示到第\(i\)个位置,当前LCS数组为sta的方案数,但是这个状态显然是\(K^K\)的。观察到一个性质:sta中的每个位置最多与前一个位置相差为\(1\),那么其实只需要记录一个差分数组就可以了。转移到的状态可以预处理。
复杂度\(O(9 * N * 2^K)\)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10, mod = 1e9 + 7;
template <typename A, typename B> inline int add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, K;
int f[2][(1 << 15) + 1][3], trans[(1 << 15) + 1][3], one[(1 << 15) + 1], ans[16];
char s[MAXN], ss[5] = "NOI";
int Get(int sta, int c) {
int pre[16] = {}, nw[16] = {};
for(int i = 1; i <= K; i++) pre[i] = pre[i - 1] + ((sta >> (i - 1)) & 1);
for(int i = 1; i <= K; i++) {
if(ss[c] == s[i]) nw[i] = pre[i - 1] + 1;
else nw[i] = max(nw[i - 1], pre[i]);
}
int ans = 0;
for(int i = 1; i <= K; i++) ans += (nw[i] - nw[i - 1]) << (i - 1);
return ans;
}
signed main() {
N = read(); K = read();
scanf("%s", s + 1);
f[0][0][0] = 1; int lim = 1 << K;
for(int sta = 0; sta < lim; sta++) {
one[sta] = one[sta >> 1] + (sta & 1);
for(int i = 0; i < 3; i++) trans[sta][i] = Get(sta, i);
}
int o = 0;
for(int i = 0; i <= N; i++) {
memset(f[o ^ 1], 0, sizeof(f[o ^ 1]));
for(int sta = 0; sta < lim; sta++) {
for(int len = 0; len < 3; len++) {
for(int c = 0; c < 3; c++) {
int nxt;
if(c == 0) nxt = 1;
else if(c == 1) nxt = (len == 1 ? 2 : 0);
else if(c == 2) nxt = (len == 2 ? 3 : 0);
if(nxt == 3) continue;
add2(f[o ^ 1][trans[sta][c]][nxt], f[o][sta][len]);
}
// cout << f[i + 1][sta][len] << '\n';
}
}
o ^= 1;
}
for(int i = 0; i < lim; i++)
for(int j = 0; j < 3; j++)
add2(ans[one[i]], f[o ^ 1][i][j]);
for(int i = 0; i <= K; i++) cout << ans[i] << '\n';
return 0;
}
/*
*/
洛谷P4590 [TJOI2018]游园会(状压dp LCS)的更多相关文章
- 洛谷P3959 宝藏(状压dp)
传送门 为什么感觉状压dp都好玄学……FlashHu大佬太强啦…… 设$f_{i,j}$表示当前选的点集为$i$,下一次要加入的点集为$j$时,新加入的点和原有的点之间的最小边权.具体的转移可以枚举$ ...
- 洛谷 P3112 后卫马克 —— 状压DP
题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...
- 【洛谷4941】War2 状压Dp
简单的状压DP,和NOIP2017 Day2 找宝藏 代码几乎一样.(比那个稍微简单一点) f[i][j] ,i代表点的状态,j是当前选择的点,枚举上一个选到的点k 然后从f[i-(1<< ...
- 洛谷 3959 宝藏——枚举+状压dp
题目:https://www.luogu.org/problemnew/show/P3959 原来写了个不枚举起点的状压dp. #include<iostream> #include< ...
- 洛谷$P3959\ [NOIp2017]$ 宝藏 状压$dp$
正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j} ...
- 洛谷 P1433 吃奶酪 状压DP
题目描述 分析 比较简单的状压DP 我们设\(f[i][j]\)为当前的状态为\(i\)且当前所在的位置为\(j\)时走过的最小距离 因为老鼠的坐标为\((0,0)\),所以我们要预处理出\(f[1& ...
- 洛谷P2473奖励关——状压DP
题目:https://www.luogu.org/problemnew/show/P2473 还是对DP套路不熟悉... 像这种前面影响后面,而后面不影响前面的问题就应该考虑倒序递推: 看n只有15那 ...
- 2018.11.02 洛谷P2831 愤怒的小鸟(状压dp)
传送门 状压一眼题. 直接f[i]f[i]f[i]表示未选择状态为iii时的最小次数. 然后考虑现在怎么转移. 显然可以直接枚举消掉某一个点或者某两个点,复杂度O(n22n)O(n^22^n)O(n2 ...
- 洛谷 P1879 玉米田(状压DP入门题)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int M,N; int plant[maxn][maxn];/ ...
随机推荐
- 第87节:Java中的Bootstrap基础与SQL入门
第87节:Java中的Bootstrap基础与SQL入门 前言复习 什么是JQ? : write less do more 写更少的代码,做更多的事 找出所有兄弟: $("div" ...
- Python中函数和模块的体验与使用
函数基础 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体验 1.1 快速体验 所谓函数,就是把 具有独立功能的代码块 组织为一个 ...
- MySQL(3)---MySQL优化
MySQL优化 一.单表.双表.三表优化 1.单表 首先结论就是,range类型查询字段后面的索引全都无效 (1)建表 create table if not exists article( i ...
- springBoot(7)---整合Mybaties增删改查
整合Mybaties增删改查 1.填写pom.xml <!-- mybatis依赖jar包 --> <dependency> <groupId>org.mybati ...
- Linux编程 22 shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)
1. 输出重定向 最基本的重定向是将命令的输出发送到一个文件中.在bash shell中用大于号(>) ,格式如下:command > inputfile.例如:将date命令的输出内容, ...
- Magicodes.NET框架之路——让代码再飞一会(ASP.NET Scaffolding)
首先感谢大家对Magicodes.NET框架的支持.就如我上篇所说,框架成熟可能至少还需要一年,毕竟个人力量实在有限.希望有兴趣的小伙伴能够加入我们并且给予贡献.同时有问题的小伙伴请不要在群里询问问题 ...
- Zookeeper系列目录
1.zookeeper安装和参数配置 2.zookeeper的适用场景 3.zookeeper客户端的实现以及使用--watcher机制 session机制 重连恢复机制 异步io
- 跟面试官聊.NET垃圾收集,直刺面试官G点
装逼的面试官和装逼的程序员 我面试别人的时候,经常是按这种路子来面试: 看简历和面试题,从简历和面试题上找到一些技术点,然后跟应聘者聊. 聊某个技术点的时候,应聘者的回答会牵涉到其他的技术点,然后我会 ...
- #21 Python异常
前言 运行程序时经常遇到各种错误,例如:ImportError(导入模块错误).IndexError(索引错误).NameError(变量错误).SyntaxError(语法错误).Indentati ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...