[agc017f]Zigzag
来源:互联网 发布:淘宝评论在哪里看 编辑:程序博客网 时间:2024/06/16 17:45
前言
DP题,我当然不会啦。
题目大意
请你找到m个n位二进制数,对于相邻两个,i+1的前j位的和不小于i的前j位的和。
此外还有对于某个二进制数某位必须是几的若干个限制。
DP
很容易想到设dp[i,s]表示做到第i个二进制数第i个是s,每次枚举前一个,复杂度很大。
转移复杂度太大了,我们来尝试优化。
如果可以不用枚举前一个就好了。
那么不如让前一个对着当前的改变吧!
设dp[i,j,s]表示做到第i个二进制数,已经确定了它的前j位和s的前j位一致,其中你只要保证了这个新的二进制数任意前缀和和s满足,就能满足限制。
这个s就是前一个变化而来的。
变化规则也很简单。
如果你确定当前位为1,s这位也是1,当然没问题。
0与0同理。
而0与1非法。
然后1与0,则为了满足s的前j位与当前二进制数前j位一致,要对s做改变。
你可以找到在这之后第一个有1的位置,让s这一位-1,第j位+1。
当然之后可能已经没有1了,这说明当前二进制数可以为所欲为,然后我们直接把第j位+1即可。
这样dp就简单了。
#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=20+10,mo=1000000007;int dp[2][maxn][(1<<21)+10],nxt[(1<<21)+10][maxn];int bz[maxn][maxn];int i,j,k,l,r,s,t,n,m,p,ans,now;int main(){ scanf("%d%d%d",&n,&m,&p); n--; fo(i,0,(1<<n)-1){ t=-1; fd(j,n-1,0){ if ((i&(1<<j))) t=j; nxt[i][j]=t; } } fo(i,1,m) fo(j,0,n-1) bz[i][j]=-1; fo(i,1,p){ scanf("%d%d%d",&j,&k,&l); bz[j][k-1]=l; } dp[0][n][0]=1; now=1; fo(i,1,m){ fo(s,0,(1<<n)-1) dp[now][0][s]=dp[1-now][n][s]; fo(j,0,n) fo(s,0,(1<<n)-1) dp[1-now][j][s]=0; fo(j,0,n-1) fo(s,0,(1<<n)-1) if (dp[now][j][s]){ fo(k,0,1){ if (bz[i][j]!=-1&&bz[i][j]!=k) continue; t=(s&(1<<j)); if (t) t=1; if (k==0&&t==1) continue; if (k==t) (dp[now][j+1][s]+=dp[now][j][s])%=mo; else{ r=nxt[s][j]; if (r==-1) (dp[now][j+1][s+(1<<j)]+=dp[now][j][s])%=mo; else (dp[now][j+1][s+(1<<j)-(1<<r)]+=dp[now][j][s])%=mo; } } } now=1-now; } fo(s,0,(1<<n)-1) (ans+=dp[1-now][n][s])%=mo; (ans+=mo)%=mo; printf("%d\n",ans);}
阅读全文
0 0
- [agc017f]Zigzag
- [agc017F]Zigzag
- zigzag
- zigzag
- ZigZag
- zigzag
- Zigzag
- ZigZag
- ZigZag
- ZigZag
- Zigzag
- ZigZag Conversion
- ZigZag Conversion
- ZigZag Conversion
- zigzag矩阵
- Zigzag Conversion
- zigzag数组
- zigzag数组
- 铺砖问题
- 硬件电路设计基础:二极管半导体
- 华为存储
- centos安装配置hadoop超详细过程【转】
- 动态规划小记
- [agc017f]Zigzag
- java序列化与反序列化(5)------反序列化时对象的创建方式
- 杂志社投稿流程
- leetcode---path-sum-ii---树
- bzoj 2815: [ZJOI2012]灾难
- 【算法】【Greedy】Patching Array
- 关于顺序表与链表的区别
- centos7.0安装kvm【转】
- 台式机组RAID(SSD 256G*2 + RAID0)