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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~