zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 80 c题 Two Arrays 隔板法

    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!!!
    
  • 相关阅读:
    JS数组常用方法参考---5、sort方法
    JS数组常用方法---1、课程介绍
    JS数组常用方法参考---4、unshift方法
    JS数组常用方法参考---3、队列对应的方法
    ES6课程---12、面向对象
    legend3---30、不同类型的网站打包方案
    数据库Sharding的基本思想和切分策略
    用sharding技术来扩展你的数据库(一)sharding 介绍
    什么是Scale Up和Scale Out?
    淘宝网采用什么技术架构来实现网站高负载的
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871801.html
Copyright © 2011-2022 走看看