Array

题目链接
题意:
对于长度为n的数组A,A中只包含从1到n的整数(可重复)。如果A单调不上升或单调不下降,A就可称为美丽的。 找出在长度为n时,有几个美丽的A。
思路:
首先考虑单调不下降的情况,令序列[x1,x2,x3,...,xn-1,xn],其中xi表示数字i的个数,可得x1+x2+x3+...+xn-1+xn=n,每一种x序列代表着一种美丽数组A,例如n=3,x1=0,x2=1,x3=2,x序列为[0,1,2],数组A为[2,3,3],故求出x序列的方案数,则为美丽数组的方案数。考虑隔板法,有n个1,n-1个隔板,上述例子用隔板法表示则为: |1|11 ,总共n+n-1=2n-1个位子,其中有n个位子是1,所以方案数为C(2n-1,n);考虑上单调不上升的情况,与单调不下降的情况恰恰对称,故总方案数为2C(2n-1,n);注意到序列[1,1,1],[2,2,2],...,[n,n,n]在单调不上升和单调不下降中都算了一次,实际方案数为2C(2n-1,n)-n;具体实现看代码细节。

点击查看代码
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long 
const ll N = 1e5+5;
ll mod=1000000007;
ll jc[N*10];
ll pw(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
void solve(){
    ll n;
    cin>>n; //读取n
    if(n==1){
        cout<<1<<endl; //n为1时方案数为1,先处理掉
        return ;
    }
    //答案化简成阶乘形式
    ll x=1;
    for(ll i=1;i<=2*n+1;++i){ //预处理出每一个数的阶乘
        x*=i;
        x%=mod; //每次计算取模
        jc[i]=x;
    }
    ll ans=2*jc[2*n-1]%mod;
    //涉及到除法之后取模,逆元的应用
    ans=ans*pw(jc[n],mod-2)%mod; 
    ans=ans*pw(jc[n-1],mod-2)%mod;
    ans-=n;
    cout<<ans<<endl;//输出答案
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _=1;
    // cin>>_;
    while(_--)
    solve();
    return 0;
}
posted @   sjgigj  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示