Codeforces 1312 D. Count the Arrays (組合數學)

E. Array Shrinking
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given an array a1,a2,…,an. You can perform the following operation any number of times:

Choose a pair of two neighboring equal elements ai=ai+1 (if there is at least one such pair).
Replace them by one element with value ai+1.
After each such operation, the length of the array will decrease by one (and elements are renumerated accordingly). What is the minimum possible length of the array a you can get?

Input
The first line contains the single integer n (1≤n≤500) — the initial length of the array a.

The second line contains n integers a1,a2,…,an (1≤ai≤1000) — the initial array a.

Output
Print the only integer — the minimum possible length you can get after performing the operation described above any number of times.

Examples
inputCopy
5
4 3 2 2 3
outputCopy
2
inputCopy
7
3 3 4 4 4 3 3
outputCopy
2
inputCopy
3
1 3 5
outputCopy
3
inputCopy
1
1000
outputCopy
1
Note
In the first test, this is one of the optimal sequences of operations: 4 3 2 2 3 → 4 3 3 3 → 4 4 3 → 5 3.

In the second test, this is one of the optimal sequences of operations: 3 3 4 4 4 3 3 → 4 4 4 4 3 3 → 4 4 4 4 4 → 5 4 4 4 → 5 5 4 → 6 4.

In the third and fourth tests, you can’t perform the operation at all.

題意:
在m個數裏面挑出n個數,n個數要先遞增後遞減,然後必須有兩個一樣的數,剩下的數各不相同。

思路:

  1. 很明顯是一道組合數學。
  2. 首先在m裏面挑出n-1個數就是Cm取n-1。
  3. 然後是保證最大的那個元素不在兩邊,剩下的n-2個元素有n-3個不同元素可以放在最大的元素的左邊或者右邊,所以是(n-2) * qpow(2,n-3) 。
  4. 因爲這裏n的範圍是大於等於2的,而快速冪無法處理負冪,所以這裏可以採用特判n=2或者用逆元處理,見代碼處。
  5. 還有就是快速冪不能帶快速乘,具體原因不知,比賽時因快速乘超時了一發,重寫快速冪才過。
  6. 如果有什麼講的不清楚的地方歡迎提出來,歡迎交流~

代碼:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define ins insert
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#pragma GCC optimize(2)
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }//��=acos(L/2R);
//void debug1(){ cout<<"I CAN AC"<<endl;}//void debug2(){printf("T A T\n");}
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){
ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}
const int manx=1e3+5;

ll Inv(ll x){
	return qp(x,mod-2,mod);
}
ll Cal(ll n,ll m){
	if (m>n) return 0;
	ll ans = 1;
	for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;
	return ans%mod;
}
int main()
{
    ll n=read(),m=read();
    ll ans=Cal(m,n-1);
    ans%=mod;
    /*特判
    if(n>2) ans=ans*qp(2,n-3,mod)%mod*(n-2)%mod;
    else ans=0;
    */
    //逆元
    ans=ans*qp(2,n-2,mod)%mod*(n-2)%mod*Inv(2);
    ans=(ans+mod)%mod;
    printf("%lld\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章