AtCoder 2370 Piling
来源:互联网 发布:一键php加mysql环境 编辑:程序博客网 时间:2024/06/07 01:16
D - Piling Up
Time limit : 2sec / Memory limit : 256MB
Score : 900 points
Problem Statement
Joisino has a lot of red and blue bricks and a large box. She will build a tower of these bricks in the following manner.
First, she will pick a total of N bricks and put them into the box. Here, there may be any number of bricks of each color in the box, as long as there are N bricks in total. Particularly, there may be zero red bricks or zero blue bricks. Then, she will repeat an operation M times, which consists of the following three steps:
- Take out an arbitrary brick from the box.
- Put one red brick and one blue brick into the box.
- Take out another arbitrary brick from the box.
After the M operations, Joisino will build a tower by stacking the 2×M bricks removed from the box, in the order they are taken out. She is interested in the following question: how many different sequences of colors of these 2×M bricks are possible? Write a program to find the answer. Since it can be extremely large, print the count modulo 109+7.
Constraints
- 1≤N≤3000
- 1≤M≤3000
Input
Input is given from Standard Input in the following format:
N M
Output
Print the count of the different possible sequences of colors of 2×M bricks that will be stacked, modulo 109+7.
Sample Input 1
2 3
Sample Output 1
56
A total of six bricks will be removed from the box. The only impossible sequences of colors of these bricks are the ones where the colors of the second, third, fourth and fifth bricks are all the same. Therefore, there are 26−2×2×2=56 possible sequences of colors.
Sample Input 2
1000 10
Sample Output 2
1048576
Sample Input 3
1000 3000
Sample Output 3
693347555
1. 任意拿出一个砖头
2. 在盒子里放一个蓝色砖头和一个红色砖头
3. 再任意拿出一个砖头
现在给出n和m,求出有多少种拿出砖头的颜色的顺序。
思路:看到是方案数,很容易想到DP,我们设计状态为f[i][j]表示前i次操作,box里还剩j个红砖的方案数。哇!一眼秒!然后发现一些奇怪的问题:貌似会重复计数。我们发现,初始状态是自己设定的,所以可能导致看起来里面的数量不同,但是会重复计算。我们只能加一维限制条件,而一般的限制条件很明天会T,我们就只能加一维布尔型,这里表示为是否盒子里拿空过红砖。f[i][j][0/1]表示前i次操作,box里还剩j个红砖,是否拿空过红砖的方案数。然后就是一些简单转移。
这里给出一个几何理解:我们需要通过一些路径,使在平面直角坐标系中,从y轴走到x=2m处,我们不难看出,互相平行的折线是相同的情况,所以我们只要给折线标记一个上界或下界,就可以保证不重复计数。
#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<iostream>#include<cmath>#include<cstdlib>#include<ctime>using namespace std;const int MAXN=3010;const int Mod=1e9+7;int f[MAXN][MAXN][2];int main(){int n,m;scanf("%d%d",&n,&m);for (int i=0;i<=n;i++){f[0][i][0]=1;}for (int i=1;i<=m;i++){for (int j=0;j<=n;j++){int k=n-j;if (j){f[i][j][1]+=f[i-1][j][1];f[i][j][1]%=Mod;f[i][j][1]+=f[i-1][j-1][1];f[i][j][1]%=Mod;if (j==1){f[i][j][1]+=f[i-1][j][0];f[i][j][1]%=Mod;f[i][j][1]+=f[i-1][j-1][0];f[i][j][1]%=Mod;}else{f[i][j][0]+=f[i-1][j][0];f[i][j][0]%=Mod;f[i][j][0]+=f[i-1][j-1][0];f[i][j][0]%=Mod;}}if (k){f[i][j][1]+=f[i-1][j][1];f[i][j][1]%=Mod;f[i][j][1]+=f[i-1][j+1][1];f[i][j][1]%=Mod;if (j==0){f[i][j][1]+=f[i-1][j][0];f[i][j][1]%=Mod;f[i][j][1]+=f[i-1][j+1][0];f[i][j][1]%=Mod;}else{f[i][j][0]+=f[i-1][j][0];f[i][j][0]%=Mod;f[i][j][0]+=f[i-1][j+1][0];f[i][j][0]%=Mod;}}}}int ans=0;for (int i=0;i<=n;i++){ans+=f[m][i][1];if (ans>Mod){ans-=Mod;}}cout<<ans<<endl; return 0;}
- AtCoder 2370 Piling
- [DP] Atcoder AGC013D. Piling Up
- Atcoder Grand Contest 013D piling Up
- AtCoder Grand Contest 013D: Piling Up 题解
- AtCoder
- AtCoder
- AtCoder
- AtCoder
- AtCoder
- Atcoder
- Domino piling
- A. Domino piling
- 50A_Domino piling
- 50A - Domino piling
- 50A Domino piling
- codeforce50A Domino piling
- codeforces A. Domino piling
- Coderforces Domino piling
- HDU 5120 (计算几何+圆相交)
- codeforces 712D Memory and Scores (dp)
- 电路交换与分组交换的区别
- IoC/DI理解
- Update 错数据恢复
- AtCoder 2370 Piling
- Unbuntu16.04+Kaldi本地运行timit语料(完整版)
- 野(wild)指针与悬空(dangling)指针
- 稳定婚姻问题
- python 使用list和tuple
- 排序算法归类
- c++实现基本栈和队列
- 如何用JavaScript代码编写拖拽
- some tips about python Three