取值
取值
时间限制: 2 Sec 内存限制: 128 MB题目描述
现给你两个整数n,m。请问有多少种对整数x1,x2,…,xn的取值,使得等式x1+x2+…+xn=m成立。你的赋值必须满足0<=x1<=x2…<=xn。例如,当m=3,n=2时,共有2种取法,分别为(x1,x2)=(0,3)或(1,2)。请输出答案除以108+7的余数。
输入
第一行为一个正整数T,表示数据组数。
接下来T行,每行两个正整数,分别为m和n。
接下来T行,每行两个正整数,分别为m和n。
输出
输出T行,分别表示对每一组数据的答案除以108+7的余数。
样例输入
2
3 2
7 3
样例输出
2
8
提示
对于10%的数据,1<=n<=m<=10。
对于30%的数据,1<=n<=m<=50。
对于50%的数据,1<=n<=m<=100。
对于100%的数据,T<=20,1<=n<=m<=300。
对于30%的数据,1<=n<=m<=50。
对于50%的数据,1<=n<=m<=100。
对于100%的数据,T<=20,1<=n<=m<=300。
题解
dp,状态转移公式:f[i][j]+=f[i-1][j-k],意思是第i个选k,总值为j时的取法数。为保证k递增,把k循环放在第一层。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define Mod 100000007 5 using namespace std; 6 const int N=303; 7 int t,n,m; 8 int f[N][N]; 9 int main() 10 { 11 f[0][0]=1; 12 for(int k=0;k<=300;k++) 13 for(int i=1;i<=300;i++) 14 for(int j=k;j<=300;j++) 15 f[i][j]=(f[i][j]+f[i-1][j-k])%Mod; 16 scanf("%d",&t); 17 while(t--) 18 { 19 scanf("%d%d",&m,&n); 20 printf("%d\n",f[n][m]); 21 } 22 return 0; 23 }