链接:https://ac.nowcoder.com/acm/problem/15442
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
wyh非常喜欢lol游戏,一天,他听说学校要选拔lol队员,他非常高兴的就去了,选拔规则是,一共有N个评委,每个评委根据线上对线能力和打团能力给出一个[0,M]之间的一个整数作为分数,然后取平均值,wyh学长非常好奇,他想知道有多少种这样的情况:
平均分等于其中某一位评委给的分数
例如2个评委,给打的分数都是1分,那么此时平均分是1分,即等于第一个评委的分数,又等于第二个评委的分数,这样答案是2
但是由于每个评委打的分都是在[0,M]之间,所以会有很多种情况。
现在请你帮助你们wyh学长数一下有多少种这样的情况,由于结果会很大,请你对1000000007取余
输入描述:
输入第一行一个整数T(1<=T<=110) 接下来有T组测试数据,对于每组测试数据输入2个数n和M(2<=n<=60,1<=M<=200),代表有n个评委,每个评委的分数都在[0,M]之间的一个整数
输出描述:
对于每组测试数据,输出对应答案
示例1
输入
1 3 1
输出
6
说明
样例解释:
对于样例有以下几种打分情况是符合要求的
其中每种情况相等的可能性都是三个,比如0分的时候,平均分和第一位、第二位、第三位都相等,所以是3中情况,1的时候也同理,所以答案为6
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll dp[61][12005];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=0;i<=m;i++) dp[0][i]=1;
for(int i=1;i<n;i++){
for(int j=0;j<=i*m;j++){
if(j<=m) dp[i][j]=dp[i-1][j];
else dp[i][j]=((dp[i-1][j]-dp[i-1][j-m-1])%mod+mod)%mod;
}
if(i!=n-1){
for(int j=1;j<=(i+1)*m;j++)
dp[i][j]=(dp[i][j]+dp[i][j-1])%mod;
}
}
ll ans=0;
for(int i=0;i<=m;i++){
ans+=dp[n-1][(n-1)*i];
ans%=mod;
}
ans=ans*n%mod;
printf("%lld\n",ans);
}
return 0;
}
枚举+多元一次不定方程求非负整数解的组数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll c[12100][65];//记忆化组合数
int n,m;
ll ksm(ll a,ll b){
ll s=1;
while(b){
if(b&1){
a%=mod;
s%=mod;
s*=a;
}
a%=mod;
a*=a;
b>>=1;
}
return s%mod;
}
ll C(int n,int m){//求组合数
if(m==0||m==n) return 1;
if(m>n-m) m=n-m;
if(c[n][m]) return c[n][m];
ll up=1,down=1;
for(int i=1;i<=m;i++){
up=(up*(n-i+1))%mod;
down=(down*i)%mod;
}
return c[n][m]=up*ksm(down,mod-2)%mod;
}
ll rc(ll n,ll k){//容斥原理求某个数>m的方程解的种数
ll ans=0;
for(int i=1;k+n-i*(m+1)-1>=n-1;i++){
if(i&1) ans+=C(n,i)*C(k+n-i*(m+1)-1,n-1)%mod;
else ans-=C(n,i)*C(k+n-i*(m+1)-1,n-1)%mod;
ans%=mod;
}
return ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
ll ans=0;
for(int i=0;i<=m;i++){
ans=(ans+n*C((n-1)*(i+1)-1,n-2))%mod;
ans-=n*rc(n-1,(n-1)*i);
ans=(ans%mod+mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}