AtCoder Grand Contest 017 F - Zigzag
题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f
题目大意:
找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若\(a<b\),则设\(a_i\)表示\(a\)的二进制下第\(i\)位(从左往右)的数,有\(a_i\leqslant b_i,i\in[1,n]\)
现需要满足每个二进制数需要小于其之后的二进制数,并且给出一些性质,满足第\(A_j\)个二进制数的第\(B_j\)位(从左往右)必须要为\(C_i\),求方案数
显然是个DP题,考虑如何DP,我们首先可以想到状压每条路径,设\(f_{i,j}\)表示当前走完第\(i\)条路径,第\(i\)条路径的表示为\(j\),转移时直接枚举下一条路径,时间复杂度\(O(2^{2·N}·M)\),枚举子集优化可以为\(O(3^N·M)\),但无论如何都过不了
考虑优化,上一个DP做法的瓶颈在于需要枚举下一条路径的状态,我们考虑不枚举,直接从当前状态下手。设\(f_{i,j,k}\)表示当前正在走第\(i\)条路径,已经走了\(j\)步,目前能走的最靠左的路径状态为\(k\)
我们枚举第\(j+1\)步向哪边移动,如果要向左走,当前位置状态必须为\(0\);如果向右走,当前位置状态为\(1\)时直接走,如果当前位置状态不为零,就把后面位置的一个\(1\)挪到这里,用位运算可以做到\(O(1)\)转移,复杂度\(O(2^N·N·M)\)

(细线为原本路径,粗线为新路径,相当于将后面的一个\(1\)提前了)
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
#define lowbit(x) ((x)&-(x))
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
int x=0,f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline int read(){
int x=0,f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int p=1e9+7;
int f[2][(1<<20)+10],C[30][30];
int main(){
int n=read()-1,m=read(),k=read();
for (int i=1;i<=k;i++){
int x=read(),y=read(),z=read();
C[x][y-1]=z+1;
}
f[0][0]=1; int now=0;
for (int i=1;i<=m;i++){
for (int j=0;j<n;j++){
now^=1;
memset(f[now],0,sizeof(f[now]));
for (int s=0;s<1<<n;s++){
if (f[now^1][s]){
if (C[i][j]!=2&&((s>>j)&1)==0) f[now][s]=(f[now][s]+f[now^1][s])%p;
if (C[i][j]!=1){
int Ns=0;
if ((s>>j)&1) Ns=s;
else{
int tmp=((-1)^((1<<(j+1))-1))&s,Ds=!tmp?0:lowbit(tmp);
Ns=s^(1<<j)^Ds;
}
f[now][Ns]=(f[now][Ns]+f[now^1][s])%p;
}
}
}
}
}
int Ans=0;
for (int s=0;s<1<<n;s++) Ans=(Ans+f[now][s])%p;
printf("%d\n",Ans);
return 0;
}
AtCoder Grand Contest 017 F - Zigzag的更多相关文章
- AtCoder Grand Contest 017 (VP)
contest link Official Editorial 比赛体验--之前做题的时候感觉 AtCoder 挺快的,现在打了VP之后发现还是会挂的--而且不是加载缓慢或者载不出来,直接给你一个无法 ...
- AtCoder Grand Contest 017
noi前橙名计划失败.全程搞C而gg…… A - Biscuits 题意:背包,求价值为奇/偶的方案数. #include<cstdio> #include<queue> #i ...
- AtCoder Grand Contest 002 F:Leftmost Ball
题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...
- AtCoder Grand Contest 003 F - Fraction of Fractal
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...
- AtCoder Grand Contest 011 F - Train Service Planning
题目传送门:https://agc011.contest.atcoder.jp/tasks/agc011_f 题目大意: 现有一条铁路,铁路分为\(1\sim n\)个区间和\(0\sim n\)个站 ...
- AtCoder Grand Contest 010 F - Tree Game
题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...
- AtCoder Grand Contest 016 F - Games on DAG
题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_f 题目大意: 给定一个\(N\)点\(M\)边的DAG,\(x_i\)有边连向\(y_i\) ...
- Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)
洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...
- Atcoder Grand Contest 015 F - Kenus the Ancient Greek(找性质+乱搞)
洛谷题面传送门 & Atcoder 题面传送门 一道难度 Au 的 AGC F,虽然看过题解之后感觉并不复杂,但放在现场确实挺有挑战性的. 首先第一问很简单,只要每次尽量让"辗转相除 ...
随机推荐
- 使用mysql导入数据时关掉binlog
在my.cnf中注释掉 log-bin=bin-log参数然后重启数据库
- glGenLists返回0或None的原因
最近调用PyOpenGL做显示,想在程序启动时候调用Display List进行显示,但是glGenLists返回None,若在程序启动后调用则没有任何问题. 搜索谷歌后,给出的解释: This ca ...
- iOS清理WebView的缓存
NSHTTPCookie *cookie; NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; ...
- Java 线程池ThreadPoolExecutor简单应用
什么是线程池: 线程池就是控制线程的一个池子.用来控制线程数量. 为什么要使用线程池: 1.避免系统反复创建和销毁线程影响执行的时间(创建+销毁>>执行时间时) 2.控制线程数量.线程过多 ...
- 查询历史使用过的命令并使用(history)
一.什么是history 在bash功能中.它能记忆使用过的命令,这个功能最大的优点就是能够查询以前做过的举动.从而能够知道你的执行步骤.那么就能够追踪你曾下达过的命令.以作为除错的工具. 二.His ...
- JavaScript 实现块级作用域
(function(){ 块级作用域: })();
- phpexcel导出后乱码或者是打不开文件必须修复的问题
百度了一下找到了解决办法,只要在header前面加上ob_end_clean();这句代码,清除缓冲区,这样就可以了,完美的解决了我的问题
- delphi 八字排盘源码(post数据以后,又分析数据)
procedure TForm1.Button14Click(Sender: TObject);var ls: TStringList; lstr: string; lss: TMemorySt ...
- 安卓AndroidManifest.xml介绍
先说一下,我的开发环境为Eclipse 3.7.1 + Android SDK + Android 1.5(API level3) Android最大的一个特点,就是用xml文件来配置,这个演习了Ja ...
- html5--6-59 其他常用CSS属性
html5--6-59 其他常用CSS属性 实例 学习要点 了解opacity属性:透明度设定 了解cursor属性:自定义鼠标样式 了解CSS新单位rem和em的区别 了解轮廓outline的设置 ...