日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【洛谷P4707】重返现世【扩展Min-Max容斥】【dp】

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【洛谷P4707】重返现世【扩展Min-Max容斥】【dp】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

題意:NNN種物品,每次第iii種產生概率為piM\frac{p_i}{M}Mpi??,∑pi=M\sum p_i=Mpi?=M。求生成KKK種不同物品的期望時間 模998244353998244353998244353

N≤1000,M≤10000,N?K≤10N \leq1000,M \leq 10000,N-K\leq10N1000,M10000,N?K10

又是神仙題……

套路性地把每個物品出現的時間丟到一個集合SSS里面,我們要求的是集合第N?K+1N-K+1N?K+1

而最小是隨便求的

所以魔改一下Min-Max容斥

假設存在f(x)f(x)f(x)滿足

max?k(S)=∑T?Sf(∣T∣)min?(T)\max_k(S)=\sum_{T \subseteq S}f(|T|)\min(T)kmax?(S)=T?S?f(T)min(T)

考慮第m+1m+1m+1大的數產生的貢獻

∑i=0mCmif(i+1)\sum_{i=0}^m C_m^if(i+1)i=0m?Cmi?f(i+1)

我們希望第kkk大的數貢獻一次 即

[m=k?1]=∑i=0mCmif(i+1)[m=k-1]=\sum_{i=0}^m C_m^if(i+1)[m=k?1]=i=0m?Cmi?f(i+1)

二項式反演一波

F(m)=[m=k?1],G(i)=f(i+1)F(m)=[m=k-1],G(i)=f(i+1)F(m)=[m=k?1],G(i)=f(i+1)

F(m)=∑i=0mCmiG(i)F(m)=\sum_{i=0}^mC_m^iG(i)F(m)=i=0m?Cmi?G(i)

G(m)=∑i=0m(?1)m?iCmiF(i)G(m)=\sum_{i=0}^m(-1)^{m-i}C_m^iF(i)G(m)=i=0m?(?1)m?iCmi?F(i)

f(m+1)=(?1)m?k+1Cmk?1f(m+1)=(-1)^{m-k+1}C_m^{k-1}f(m+1)=(?1)m?k+1Cmk?1?

f(m)=(?1)m?kCm?1k?1f(m)=(-1)^{m-k}C_{m-1}^{k-1}f(m)=(?1)m?kCm?1k?1?

所以

max?k(S)=∑T?S(?1)∣T∣?kC∣T∣?1k?1min?(T)\max_k(S)=\sum_{T \subseteq S}(-1)^{|T|-k}C_{|T|-1}^{k-1}\min(T)kmax?(S)=T?S?(?1)T?kCT?1k?1?min(T)

當然是期望下的

子集最小可以隨便求,所以考慮前面那坨怎么搞

考慮dp

定義狀態dp(i,j,k)dp(i,j,k)dp(i,j,k)表示從前iii個物品選出ppp的和為jjj作為TTT(?1)∣T∣?kC∣T∣?1k?1(-1)^{|T|-k}C_{|T|-1}^{k-1}(?1)T?kCT?1k?1?的和

考慮轉移

不選當前點 即dp(i?1,j,k)dp(i-1,j,k)dp(i?1,j,k)

選當前點 即

∑i∈T(?1)∣T∣?kC∣T∣?1k?1\sum_{i\in T}(-1)^{|T|-k}C_{|T|-1}^{k-1}iT?(?1)T?kCT?1k?1?

iii丟掉

∑T(?1)∣T∣?k+1C∣T∣k?1\sum_T(-1)^{|T|-k+1}C_{|T|}^{k-1}T?(?1)T?k+1CTk?1?

注意此時的TTT在前i?1i-1i?1個中選

由于前后的TTT不統一,無法轉移,所以……拆組合數

∑T(?1)∣T∣?k+1C∣T∣?1k?1+∑T(?1)∣T∣?k+1C∣T∣?1k?2\sum_T(-1)^{|T|-k+1}C_{|T|-1}^{k-1}+\sum_T(-1)^{|T|-k+1}C_{|T|-1}^{k-2}T?(?1)T?k+1CT?1k?1?+T?(?1)T?k+1CT?1k?2?

?∑T(?1)∣T∣?kC∣T∣?1k?1+∑T(?1)∣T∣?k+1C∣T∣?1k?2-\sum_T(-1)^{|T|-k}C_{|T|-1}^{k-1}+\sum_T(-1)^{|T|-k+1}C_{|T|-1}^{k-2}?T?(?1)T?kCT?1k?1?+T?(?1)T?k+1CT?1k?2?

再次強調是前i?1i-1i?1個中選的

所以就是

dp(i,j,k)=dp(i?1,j,k)+dp(i?1,j?pi,k?1)?dp(i?1,j?pi,k)dp(i,j,k)=dp(i-1,j,k)+dp(i-1,j-p_i,k-1)-dp(i-1,j-p_i,k)dp(i,j,k)=dp(i?1,j,k)+dp(i?1,j?pi?,k?1)?dp(i?1,j?pi?,k)

然而還有個讓人頭大的邊界問題

j<pij<p_ij<pi?也就是不能選當前點 dp(i,j,k)=dp(i?1,j,k)dp(i,j,k)=dp(i-1,j,k)dp(i,j,k)=dp(i?1,j,k)

j=pij=p_ij=pi?

如果要選就是從空集轉移過來,但空集代進去超過了人類的認知,所以直接用定義算

顯然就是∣T∣=1|T|=1T=1

(?1)1?kC0k?1=[k=1](-1)^{1-k}C_0^{k-1}=[k=1](?1)1?kC0k?1?=[k=1]

所以dp(i,j,k)=dp(i?1,j,k)+[k=1]dp(i,j,k)=dp(i-1,j,k)+[k=1]dp(i,j,k)=dp(i?1,j,k)+[k=1]

j>pij>p_ij>pi?正常轉移

滾動數組優化一下即可

#include <iostream> #include <cstdio> #include <cstring> #include <cctype> using namespace std; const int MOD=998244353; typedef long long ll; int p[1005],dp[2][10005][15]; inline int qpow(int a,int p) {int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;p>>=1;}return ans; } #define inv(x) qpow(x,MOD-2) int main() {int N,K,M;scanf("%d%d%d",&N,&K,&M);K=N-K+1;for (int i=1;i<=N;i++) scanf("%d",&p[i]);int cur=1;for (int i=1;i<=N;i++){for (int j=0;j<p[i];j++)for (int k=1;k<=K;k++)dp[cur][j][k]=dp[cur^1][j][k];for (int k=1;k<=K;k++) dp[cur][p[i]][k]=dp[cur^1][p[i]][k]+(k==1);for (int j=p[i]+1;j<=M;j++)for (int k=1;k<=K;k++)dp[cur][j][k]=((ll)dp[cur^1][j][k]+dp[cur^1][j-p[i]][k-1]-dp[cur^1][j-p[i]][k]+MOD)%MOD;cur^=1;}int ans=0;for (int i=1;i<=M;i++) ans=(ans+(ll)dp[N&1][i][K]*M%MOD*inv(i)%MOD)%MOD;printf("%d",(ans+MOD)%MOD);return 0; }

總結

以上是生活随笔為你收集整理的【洛谷P4707】重返现世【扩展Min-Max容斥】【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。