You are given two integers n and m. Calculate the number of pairs of arrays (a,b) such that:
the length of both arrays is equal to m;
each element of each array is an integer between 1 and n (inclusive);
ai≤bi for any index i from 1 to m;
array a is sorted in non-descending order;
array b is sorted in non-ascending order.
As the result can be very large, you should print it modulo 109+7.
Input
The only line contains two integers n and m (1≤n≤1000, 1≤m≤10).
Output
Print one integer – the number of arrays a and b satisfying the conditions described above modulo 109+7.
Examples
inputCopy
2 2
outputCopy
5
inputCopy
10 1
outputCopy
55
inputCopy
723 9
outputCopy
157557417
Note
In the first test there are 5 suitable arrays:
a=[1,1],b=[2,2];
a=[1,2],b=[2,2];
a=[2,2],b=[2,2];
a=[1,1],b=[2,1];
a=[1,1],b=[1,1]
题意: 有两个长度都是m的数组 a和b ,数组中元素都是不大于n的正整数,数组a是非递减数组,b是非递增数组,要求对任意的下标i、都有ai<=bi 问满足条件的数组对(a,b)共有多少种
思路:我是想枚举数组a的最后一个数(即:最大值)当这个数确定时,满足条件的数组b的最小值一定大于等于这个数 接下来先看数组a 假设a的最大值就是 n ,那么假设 xi表示 i 这个数出现的次数 那么 x1+x2+…+xn==m(总的出现次数)那么是不是相当于把 m 个球放到 n 个盒子中(盒子允许为空)我们知道把m个球放到n个非空的盒子中的求法,那么怎么转变呢? 可以每个盒子都先放一个球,那么是不是把 n+m 个球放到 m 个非空盒子了 试想每个数字出现的次数有了 那么这个非递减序列不就确定了 就是说 刚才求的放球的方法数就是我们要找的序列数 (上面是看的大佬的题解 隔板法 tql) 我们把数组a的每个最大值的情况都先求一遍 对于数组b可以看成a的逆序列 用隔板法求是一样的思路 只是盒子的数量变一变 a b 两种情况求完后 对应的情况相乘就好了 (文末有惊喜)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll ji[2000];//阶乘
void init()
{
ji[0]=1;
for(int i=1;i<2000;i++)
ji[i]=(ji[i-1]*i)%mod;
return ;
}
ll ksm(ll a,ll b)//快速幂 该好好记记了!!!
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
b/=2;
a=a*a%mod;
}
return ans%mod;
}
ll c(int m,int n)//排列组合 需要用逆元
{
return (ji[m]*ksm(ji[n]*ji[m-n]%mod,mod-2))%mod;
}
int main()
{
init();
ll dp[10000],dpp[10000];
ll n,m;
cin>>n>>m;
dp[n]=dpp[1]=1;
for(int i=1;i<=n;i++)
dp[i]=(c(m+n-i,n-i))%mod;
for(int i=2;i<=n;i++)
dpp[i]=(c(m+i-2,i-1))%mod;
ll ans=0;
for(int i=1;i<=n;i++)
ans=(ans+dp[i]*dpp[i]%mod)%mod;
cout<<ans<<endl;
return 0;
}```
大佬的思路是 b是非递增序列 那把 b 反转 接到 a 之后 这整个序列都是一个非递增序列了 2m 个球 n 个盒子 搞定了 !!!
tql!!!
tql!!!
tql!!!