取值

题目描述
现给你两个整数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行,分别表示对每一组数据的答案除以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。

思路
题目要求赋值必须满足0<=x1<=x2…<=xn,因此,对于一种答案序列有两种取法,一种是减小序列长度,即将一位赋为0,另一种是将剩下的位全部增加1个单位,当剩余值=0或者剩余位为1时,就只剩一下一种答案,根据此递归求解即可

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=305;
const int M=4005;
const int INF=0x3f3f3f;
const ull sed=31;
const int mod=1e8+7;
const double eps=1e-8;
const double PI=acos(-1.0);
typedef pair<int,int>P;
 
int T,m,n;
int ans[N][N];
 
int dfs(int x,int y)
{
    if(ans[x][y]) return ans[x][y];
    if(x==0 || y==1) return 1;
    if(x<y) return dfs(x,x)%mod;
    return ans[x][y]=(dfs(x,y-1)%mod+dfs(x-y,y)%mod)%mod;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(ans,0,sizeof(ans));
        scanf("%d%d",&n,&m);
        printf("%d\n",dfs(n,m)%mod);
    }
    return 0;
}
发布了235 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43935894/article/details/104137666