题解劝退系列

设长的那个串是A,短的那个串是B。

那我们在如果已经知道某个A的时候,A[1..i]和B[1..j]的最长公共子序列$f[i][j]=max\{f[i-1][j],f[i][j-1],f[i-1][j-1]+(A[i]==B[i])\}$

于是可以递推来枚举A,顺手把NOI的情况判掉。但这复杂度显然过不了。

注意到在推的时候,每新加一个字符,就可以由f[i-1]推出f[i],也就是说,我们根本不用记递推出来的这个A具体是什么,只要记住这个f[i]就可以了。

怎么记呢?注意到f[i][j]只能等于f[i][j-1]或者f[i][j-1]+1,也就是说,我们可以先差分这个f[i],然后状压就能记下来了。

设trans[s][k]表示原本f数组状态是s、新加了一个k字符,转移到的状态

那么可以得到递推式$g[i+1][trans[s][k]]=\sum{g[i][s]}$,g[N][s]就是最后状态s的情况数,只要统计一下s中1的个数,记到答案里就行了。

然而还要判NOI

其实很简单,只要给g多记一维,用来表示现在这个状态已经匹配到了NOI的几位就可以了

(0,1,2通过"N"转移到1;1通过“O”转移到2;2通过“I”转移到3(这个情况不合法))

要开滚动数组

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<ctime>
#include<set>
#define pa pair<int,int>
#define lowb(x) ((x)&(-(x)))
#define REP(i,n0,n) for(i=n0;i<=n;i++)
#define PER(i,n0,n) for(i=n;i>=n0;i--)
#define MAX(a,b) ((a>b)?a:b)
#define MIN(a,b) ((a<b)?a:b)
#define CLR(a,x) memset(a,x,sizeof(a))
#define rei register int
using namespace std;
const int maxn=,maxk=,maxs=,p=1e9+;
typedef long long ll; ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,K,M;
int wd[maxk],ans[maxk],ne[][];
int f[][maxs][],trans[maxs][],cnt[maxs]; inline void modadd(int &x,int y){x=(x+y)%p;} int main(){
//freopen(".in","r",stdin);
rei i,j,k,l;
N=rd(),K=rd();M=<<K;
i=;while(i<K){
char c=getchar();
if(c=='N') wd[++i]=;
else if(c=='O') wd[++i]=;
else if(c=='I') wd[++i]=;
}
REP(i,,M-){
REP(j,,){
int s=,sum=,lst=,now=;
REP(k,,K){
if(wd[k]==j) now=sum+;
if(i&(<<(k-))) sum++;
if(wd[k]!=j) now=sum;
s+=(now>lst)<<(k-);lst=MAX(lst,now);
}trans[i][j]=s;cnt[i]=sum;
//printf("%d %d %d %d\n",i,j,s,sum);
}
}
ne[][]=;ne[][]=ne[][]=ne[][]=;
bool b=;f[][][]=;
REP(i,,N-){
//memcpy(f[b],f[b^1],sizeof(f[b]));
CLR(f[b^],);
REP(j,,M-){
REP(l,,){if(!f[b][j][l]) continue;
REP(k,,){
if(l==&&k==) continue;
modadd(f[b^][trans[j][k]][ne[l][k]],f[b][j][l]);
//printf("f[%d][%d][%d]=%d -%d> ",i,j,l,f[b][j][l],k);
// printf("f[%d][%d][%d]=%d\n",i+1,trans[j][k],ne[l][k],f[b^1][trans[j][k]][ne[l][k]]);
}
}
}b^=;
}
REP(i,,M-){
REP(j,,)
modadd(ans[cnt[i]],f[b][i][j]);
}REP(i,,K) printf("%d\n",ans[i]);
return ;
}

tjoi2018D2T2(luogu4590) 游园会 (状压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) ...

随机推荐

  1. AtCoder ExaWizards 2019 简要题解

    AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...

  2. python棋类游戏编写入门

    刚接触棋类游戏程序编写的朋友,往往比较迷惑,不知从何下手. 本文总结了棋类游戏的主程序流程.计算机走子策略.打分方式(以井字棋.黑白棋.五子棋为例),未使用minimax算法,比较简单,适合刚接触的朋 ...

  3. PMO在组织中实现价值应做的工作

    PMO在组织中实现价值应做的工作 研发人员及项目经理常常对PMO有反感情绪,认为其不熟悉业务流程与技术.经常要求项目经理和研发人员提交形式化的材料,只审批和监控,不能为项目提供良好的服务.在很多企业, ...

  4. Linux lsof 命令

    lsof(list open files)是一个查看进程打开的文件的工具. 在 linux 系统中,一切皆文件.通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以 lsof 命令不仅可以查 ...

  5. grep精确匹配搜索某个单词的用法 (附: grep高效用法小结))

    grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正 ...

  6. SCRUM 12.23

    距离第二轮迭结束只有几天了. 我们全体组员现在的工作方向都在应用测试上. 明天的任务分配如下 成员 已完成任务 新任务 彭林江 落实API 自动爬虫测试 王卓 提升爬虫程序性能 正确性测试 郝倩 提升 ...

  7. BugPhobia团队篇章:团队管理与Github源代码管理说明

    0x00:序言 To the searching tags, you may well fall in love withhttp://xueba.nlsde.buaa.edu.cn/ 再见,无忧时光 ...

  8. 剑指offer:字符串的排列

    题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: ...

  9. 第三次Sprint

    Not CHECKED OUT CHECKED OUT DONE!: SPRINT GOAL: BETA-READY 修改bug 完善界面

  10. php配置虚拟主机

    在httpd.conf的目录下,新建一个配置文件virtualhost-host.conf,添加虚拟主机配置 <VirtualHost *:80> DocumentRoot "E ...