G.The Galactic Olympics(dp)

Description
n场不同的比赛,派k个人去,一个人可以参加多场比赛且至少参加一场,每场比赛只能且必须要有一个人参加,问方案数
Input
第一行一整数T表示用例组数,每组用例输入两个整数n和k分别表示比赛数和人数(1<=k<=1e6,1<=n<=1e3)
Output
输出方案数
Sample Input
1
3 2
Sample Output
6

总结:

做这一类求方案数的题时,不要总想着用组合数一个表达式就算出来,会重复计算啥的=-=

组合数学做不出来,换一种思路,用dp。

题解

dp[i][j],i为场数,j为人数,dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*j。前一项是前i-1场比赛有j个人参加,第i场比赛从j个人中任选一个人出来。

后一项是前i-1场比赛有j-1人参加,第i场比赛分配给第j个人,而第j个人有j种情况。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 1e3+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
int n,k,t;ll dp[N][N];
int main()
{
  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  cin>>t;
  dp[0][0]=1;
  rep(i,1,1e3)
      rep(j,1,1e3)
          dp[i][j]=(dp[i-1][j]*j+dp[i-1][j-1]*j)%mod;
  while(t--){
      cin>>n>>k;
      if(n<k) cout<<0<<endl;
      else cout<<dp[n][k]<<endl;
  }
  return 0;
}
原文地址:https://www.cnblogs.com/FZUlh/p/12273994.html