[DP]销售

[提交] [状态] [命题人:admin]

题目描述

农夫 John 正在筹划从他的谷仓中售出 N 头奶牛,与此同时也有 N 个农夫想要购买奶牛。每个农夫都有刚好足够购买一头奶牛的钱并且将会把买来的这头奶牛用来挤奶。为了减少买来的牛挤不出奶的风险,农夫们每个人都将会购买两头不同的奶牛各自一半的产权,然后将获得每头牛产奶量的一半。
如果将两种方案中每个农夫都购买了相同的奶牛看作是相同的销售方案。那么农夫 John 一共有多少种不同的销售方案呢?
 

 

输入

第一行包含一个整数t ≤ 100,为数据的组数。接下来t行每行包含一个整数N ≤ 2000作为输入数据。

 

输出

对于每组数据,输出农夫 John 销售奶牛的不同方案数。由于这个数有可能会很大,因此请将答案对107 + 7取模后输出。

 

样例输入

3
1
2
3

样例输出

0
1
6

 

提示

对于50%的数据,N≤20,
对于100%的数据,N≤2000.

思路:dp[i]表示i头牛的方案数,则dp[i]=(i-1)*2*dp[i-1]+(i-1)*(i-2)*dp[i-1]+(i-1)*(i-1)*dp[i-2]+(i-1)*C(i-1,2)*dp[i-2];
AC代码:
#include<bits/stdc++.h>
#define mod 10000007
typedef long long ll;
using namespace std;
 
ll dp[2005];
 
void init(){
  dp[1]=0;
  dp[2]=1;
  for(ll i=3;i<=2000;i++){
    dp[i]=(dp[i]+(i-1)*2*dp[i-1]%mod+(i-1)*(i-2)*dp[i-1]%mod)%mod;
    dp[i]=(dp[i]+(i-1)*(i-1)*dp[i-2]%mod+(i-1)*(i-2)/2*(i-1)*dp[i-2]%mod)%mod;
  }
}
 
int main()
{
    init();
    ll t;scanf("%lld",&t);
    while(t--){
        ll n;scanf("%lld",&n);
        printf("%lld\n",dp[n]);
    }
    return 0;
}
View Code

 

posted @ 2019-07-08 22:13  l..q  阅读(218)  评论(0编辑  收藏  举报