Atcoder Grand Contest 013D - Piling Up

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

  • 1N3000
  • 1M3000

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

Copy
2 3

Sample Output 1

Copy
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 262×2×2=56 possible sequences of colors.


Sample Input 2

Copy
1000 10

Sample Output 2

Copy
1048576

Sample Input 3

Copy
1000 3000

Sample Output 3

Copy
693347555

题意:给N个球(有两种颜色,初始颜色所有可能都有),你进行M次操作,问最后取出的球的序列有多少个不同的

操作定义:取出一个球,放进一个红球和一个蓝球,取出一个球

题解:考虑dp

dp[i][j]表示当前是第i次操作,当前有j个红球

这样显然会算重,于是我们考虑一个类似于最小表示法的东西

对于每种方案,我们让初始的红球个数尽可能少,这样一定存在某个时刻红球个数为0

这样我们可以用dp[i][j][0/1]来dp了

#include 
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

const int MAXN = 3005;
const int mod = 1e9 + 7;

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

int n, m, dp[MAXN][MAXN][2], ans;

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	scanf( "%d%d", &n, &m );
	for( int i = 1 ; i <= n ; i++ ) dp[ 0 ][ i ][ 0 ] = 1;
	dp[ 0 ][ 0 ][ 1 ] = 1;
	for( int i = 0 ; i < m ; i++ )
		for( int j = 0 ; j <= n ; j++ )
			for( int k = 0 ; k < 2 ; k++ ) if( int cur = dp[ i ][ j ][ k ] )
			{
				if( !j )
				{
					inc( dp[ i + 1 ][ j ][ 1 ], cur );
					inc( dp[ i + 1 ][ j + 1 ][ 1 ], cur );	
				}
				else if( j == n )
				{
					inc( dp[ i + 1 ][ j ][ k | ( j == 1 ) ], cur );
					inc( dp[ i + 1 ][ j - 1 ][ k | ( j == 1 ) ], cur );
				}
				else
				{
					inc( dp[ i + 1 ][ j ][ k ], cur );
					inc( dp[ i + 1 ][ j + 1 ][ k ], cur );
					inc( dp[ i + 1 ][ j ][ k | ( j == 1 ) ], cur );
					inc( dp[ i + 1 ][ j - 1 ][ k | ( j == 1 ) ], cur );
				}
			}
	for( int i = 0 ; i <= n ; i++ ) inc( ans, dp[ m ][ i ][ 1 ] );
	return printf( "%d\n", ans ), 0;
}


你可能感兴趣的:(Atcoder Grand Contest 013D - Piling Up)