AGC017 F - Zigzag
Time limit : 4sec / Memory limit : 256MB
Score : 1600 points
Problem Statement
There are N(N+1)⁄2 dots arranged to form an equilateral triangle whose sides consist of N dots, as shown below. The j-th dot from the left in the i-th row from the top is denoted by (i,j) (1≤i≤N, 1≤j≤i). Also, we will call (i+1,j) immediately lower-left to (i,j), and (i+1,j+1) immediately lower-right to (i,j).

Takahashi is drawing M polygonal lines L1,L2,…,LM by connecting these dots. Each Li starts at (1,1), and visits the dot that is immediately lower-left or lower-right to the current dots N−1 times. More formally, there exist Xi,1,…,Xi,N such that:
- Li connects the N points (1,Xi,1),(2,Xi,2),…,(N,Xi,N), in this order.
- For each j=1,2,…,N−1, either Xi,j+1=Xi,j or Xi,j+1=Xi,j+1 holds.
Takahashi would like to draw these lines so that no part of Li+1 is to the left of Li. That is, for each j=1,2,…,N, X1,j≤X2,j≤…≤XM,j must hold.
Additionally, there are K conditions on the shape of the lines that must be followed. The i-th condition is denoted by (Ai,Bi,Ci), which means:
- If Ci=0, LAi must visit the immediately lower-left dot for the Bi-th move.
- If Ci=1, LAi must visit the immediately lower-right dot for the Bi-th move.
That is, XAi,Bi+1=XAi,Bi+Ci must hold.
In how many ways can Takahashi draw M polygonal lines? Find the count modulo 1000000007.
Notes
Before submission, it is strongly recommended to measure the execution time of your code using "Custom Test".
Constraints
- 1≤N≤20
- 1≤M≤20
- 0≤K≤(N−1)M
- 1≤Ai≤M
- 1≤Bi≤N−1
- Ci=0 or 1
- No pair appears more than once as (Ai,Bi).
Input
Input is given from Standard Input in the following format:
N M K
A1 B1 C1
A2 B2 C2
:
AK BK CK
Output
Print the number of ways for Takahashi to draw M polygonal lines, modulo 1000000007.
Sample Input 1
3 2 1
1 2 0
Sample Output 1
6
There are six ways to draw lines, as shown below. Here, red lines represent L1, and green lines represent L2.
Sample Input 2
3 2 2
1 1 1
2 1 0
Sample Output 2
0
Sample Input 3
5 4 2
1 3 1
4 2 0
Sample Output 3
172
Sample Input 4
20 20 0
Sample Output 4
881396682 题目大意
有一高度为N的三角形,共有M条线从顶部走到底部,要求第L+1条线不能在第L条线的左边,有K个要求,要求第a条线必须在第b层向某方向走(c为一即向左,为二则向右),问共有几种情况
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int dp[1048580];
int need1[21],need2[21];
int put[1048580],go[1048580][21];
//go是记录将一条先向左再向右边翻折后的形状
//put记录自下向上找,第一个向左的边
int n,m,k;
int main()
{ int i,j,p,q,a,b,c;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=k;i++){
scanf("%d%d%d",&a,&b,&c);
a--,b--;
need1[a]|=(1<<b);
need2[a]|=(1<<b)*c;
//必须走的路径
}
n--;
memset(go,-1,sizeof(go));
memset(put,-1,sizeof(put));
for(i=0;i<(1<<n);i++){
int num=0;
for(j=0;j<n;j++)
if(i&(1<<j)){
if(j>0&&!(i&(1<<(j-1)))){
go[i][num]=i^(1<<j)^(1<<(j-1));
//i指路径,num指是第几个向右的边
}
num++;
}
}
for(i=0;i<(1<<n);i++)
for(j=n-1;j>=0;j--){
if((i&(1<<j)))continue;
put[i]=i^(1<<j);
break;
}
dp[0]=1;
for(i=0;i<m;i++){
for(j=0;j<(1<<n);j++)
if(put[j]){
dp[put[j]]+=dp[j];
dp[put[j]]%=1000000007;
}
for(p=0;p<n;p++)
for(j=(1<<n)-1;j>=0;j--)
if(go[j][p]!=-1){
dp[go[j][p]]+=dp[j],
dp[go[j][p]]%=1000000007;
}
for(j=0;j<(1<<n);j++)
if((j&need1[i])!=need2[i])
dp[j]=0;
}
int ans=0;
for(i=0;i<(1<<n);i++)
ans+=dp[i],
ans%=1000000007;
printf("%d\n",ans%1000000007);
return 0;
}
AGC017 F - Zigzag的更多相关文章
- AtCoder Grand Contest 017 F - Zigzag
题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...
- 【AtCoder】AGC017
在此处输入标题 标签(空格分隔): 未分类 A - Biscuits dp[i][0/1]表示当前和是偶数还是奇数,直接转移即可 #include <bits/stdc++.h> #def ...
- AtCoder Grand Contest 017
noi前橙名计划失败.全程搞C而gg…… A - Biscuits 题意:背包,求价值为奇/偶的方案数. #include<cstdio> #include<queue> #i ...
- Codeforces Round #557 (Div. 1) 简要题解
Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...
- AtCoder Grand Contest 017 (VP)
contest link Official Editorial 比赛体验--之前做题的时候感觉 AtCoder 挺快的,现在打了VP之后发现还是会挂的--而且不是加载缓慢或者载不出来,直接给你一个无法 ...
- Mysql_以案例为基准之查询
查询数据操作
- [LeetCode] ZigZag Converesion 之字型转换字符串
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- No.006:ZigZag Conversion
问题: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows l ...
- leetcode 6. ZigZag Conversion
https://leetcode.com/problems/zigzag-conversion/ 题目: 将字符串转化成zigzag模式. 例如 "abcdefghijkmlnpq" ...
随机推荐
- python云算法
http://www.runoob.com/python3/python3-basic-operators.html 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中, ...
- 给织梦DEDECMS添加栏目图片与英文名显示
开始做微网站了,不同于传统手机网站,因为微信上的微网站是支持CSS3与HTML5的,好吧,各种要学习的还有很多很多阿~这么多新代码,叹! 本来想转战帝国CMS了,奈何这名字太不对味了,PHPCMS也懒 ...
- java垃圾回收的分类
1.线程数 分为串行垃圾回收器和并行垃圾回收器.串行垃圾回收器一次只使用一个线程进行垃圾回收:并行垃圾回收器一次将开启多个线程同时进行垃圾回收.在并行能力较强的 CPU 上,使用并行垃圾回收器可以缩短 ...
- 将js进行到底:node学习笔记1
废话:自高中以来一直对编程充满激情,磨剑五年,如今要毕业了,我不想用我已经擅长的知识敷衍,而想以一个全新的领域去面向我的毕设--是时候学习一下node.js node.js基础 对于JavaScrip ...
- addTarget:self 的意思是说,这个方法在本类中
addTarget:self 的意思是说,这个方法在本类中也可以传入其他类的指针*/
- Mysql Nested-Loop Join Algorithms
MySQL在多表之间执行join时,利用一种nested-loop algorithm 或者其变种:(嵌套循环) Nested-Loop Join Algorithm 一个简单的嵌套循环连 ...
- 直接请求转发(Forward)和间接请求转发(Redirect)两种区别?
用户向服务器发送了一次HTTP请求,该请求肯能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉不到请求转发的.根据转发方式的不同,可以区分为直接请求转发 ...
- java中的按位与运算
package scanner; public class SingleAnd { public static void main(String[] args) { int[] first = {10 ...
- redux学习日志:关于异步action
当我们在执行某个动作的时候,会直接dispatch(action),此时state会立即更新,但是如果这个动作是个异步的呢,我们要等结果出来了才能知道要更新什么样的state(比如ajax请求),那就 ...
- mysql视图定义、原理、创建、使用
定义: 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并在引用视图时 ...