牛客練習賽69 D 火柴排隊

2021-10-09 12:16:51 字數 2269 閱讀 6400

長度為 n

nn 序列 a

aa 中找出 k

kk 個數加 d

dd,使新序列中如果 ai′

>aj

′a'_i>a'_j

ai′​

>aj

′​,那麼原序列也 a

i>aj

a_i>a_j

ai​>aj

​ 的概率。

對於每個 1≤k

≤n

1\le k\le n

1≤k≤

n,你都要輸出其對應的答案,答案模 998244353

998244353

998244

353。

等價於乙個單調上公升的序列選 k

kk 個數加 d

dd 後仍單調上公升的概率。

記 d p[

i][j

][0/

1]

dp[i][j][0/1]

dp[i][

j][0

/1] 為前 i

ii 個數選了 j

jj 個數加上 d

dd 且當前數是否選擇,滿足題意的方案數:

邊界:dp[

1][0

][0]

=dp[

1][1

][1]

=1

dp[1][0][0]=dp[1][1][1]=1

dp[1][

0][0

]=dp

[1][

1][1

]=1

狀態轉移方程:

dp[i][j][0]=dp[i-1][j][0]+dp[i-1][j][1]*(a[i-1]+d>a[i])\\ dp[i][j][1]=dp[i-1][j-1][0]+dp[i-1][j-1][1] \end

}

(kn​)d

p[n]

[k][

0]+d

p[n]

[k][

1]​ 就是答案。

#include

#define sz(x) (int)(x).size()

#define all(x) (x).begin(),(x).end()

#define pb push_back

#define eb emplace_back

#define mp make_pair

#define fi first

#define se second

using

namespace std;

typedef

double db;

typedef

long

long ll;

typedef pair<

int,

int> pii;

typedef vector<

int> vi;

typedef vector vpii;

//head

const

int n=

5005

;const ll mod=

998244353

;int n,d,a[n]

;ll fac[n]

,invf[n]

,dp[2]

[n][2]

;ll fpow

(ll a,ll b)

return ret;

}int

main()

fac[0]

=1;for

(int i=

1;i<=n;i++

) fac[i]

=fac[i-1]

*i%mod;

invf[n]

=fpow

(fac[n]

,mod-2)

;for

(int i=n-

1;i>=

1;i--

) invf[i]

=invf[i+1]

*(i+1)

%mod;

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,(dp[n&1]

[i][0]

+dp[n&1]

[i][1]

)%mod*fac[i]

%mod*fac[n-i]

%mod*invf[n]

%mod)

;return0;

}

牛客練習賽69D 火柴排隊 dp

n nn個數的序列,排序後讓隨機k kk個數加上d dd,求依舊滿足單調上公升的期望概率 對於乙個位置加上d dd後會讓到後面一段範圍內都得加上d dd。我們預處理乙個l il i li 表示如果i ii加上d dd後 i 1,li i 1,l i i 1,l i 都得加上ddd。然後設fi,jf ...

牛客練習賽 69

第一次打牛客直接。y1s1牛客的評測系統真的慢,搞得我不想交 題目鏈結 首先先對陣列a逆序貪心可得val i,j a1 a2 ai j val i,j a 1 a 2 dots a val i,j a 1 a 2 ai j 嘗試證明 分析可知我們最終會選擇i j i ji j個陣列a的數,貪心肯定每...

牛客練習賽69 B

題意 給定n nn個數,乙個x xx表示可以劃分成最多x xx個串,乙個y yy表示在乙個串中最多選擇y yy個數。最後求 i 1x j 1yv al i j sum x sum yval i,j i 1x j 1 y va l i,j v al i,j val i,j val i,j 為 將n n...