Codeforces Round #309 (Div. 2): C. Kyoya and Colored Balls(DP)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/83094315

 

C. Kyoya and Colored Balls

Kyoya Ootori has a bag with n colored balls that are colored with k different colors. The colors are labeled from 1 to k. Balls of the same color are indistinguishable. He draws balls from the bag one by one until the bag is empty. He noticed that he drew the last ball of color ibefore drawing the last ball of color i + 1 for all i from 1 to k - 1. Now he wonders how many different ways this can happen.

Input

The first line of input will have one integer k (1 ≤ k ≤ 1000) the number of colors.

Then, k lines will follow. The i-th line will contain ci, the number of balls of the i-th color (1 ≤ ci ≤ 1000).

The total number of balls doesn't exceed 1000.

Output

A single integer, the number of ways that Kyoya can draw the balls from the bag as described in the statement, modulo 1 000 000 007.

Examples

input

3
2
2
1

output

3

题意:

有k种颜色的气球,第i种颜色的气球有sum[i]个,问有多少种不同的排列方式满足每种颜色的最后一个气球,后面一定紧接着下一种颜色的气球

思路:

dp[x][y]表示只考虑前x种颜色的气球,且当前最后一个气球在位置y上的方案数

可以得到dp[x][y] = C(y-1, sum[x]-1)*dp[x-1][y-sum[x]]

看似二维DP但是复杂度实际上是线性的,可以用记忆化搜索搞定

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
LL C[1005][1005];
int sum[1005];
LL Sech(int n, int m)
{
	if(n==1)
		return 1;
	return C[m-1][sum[n]-1]*Sech(n-1, m-sum[n])%mod;
}
int main(void)
{
	int m, n, i, j;
	for(i=0;i<=1002;i++)
		C[i][0] = 1;
	for(i=1;i<=1002;i++)
	{
		for(j=1;j<=i;j++)
			C[i][j] = (C[i-1][j-1]+C[i-1][j])%mod;
	}
	m = 0;
	scanf("%d", &n);
	for(i=1;i<=n;i++)
	{
		scanf("%d", &sum[i]);
		m += sum[i];
	}
	printf("%lld\n", Sech(n, m));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/83094315
今日推荐