CSP校內集訓 kat(期望DP)

2022-03-16 23:58:07 字數 1490 閱讀 4513

一本有n道題的練習冊,katarina大佬每天都會做k道題。

第一天做第1k題,第二天做第2k+1題……第n-k+1天做第n−k+1~n道題。

每道題有它的難度值,假設今天katarina大佬做的題目中最大難度為t,那麼今天katarina大佬的勞累度就是\(w_t\),做完這本書的勞累值就是每天的勞累值之和。

題目的難度在1~m隨機,求做完整本書的期望勞累值

\(n,m \leq 500 , mod = 10^9+7\)

由於前面兩道題都有點迷所以還以為這道題也是道神題

性質:求每種排列的貢獻和 等價於 乙個滑動視窗的貢獻\(\times\)

\((n-k+1)\)

(**)證明

根據題意有:$$ans = \sum_ \times (a_1^i + a_2^i + ....... + a_^i)) }$$其中\(a_j^i\)表示在第\(i\)種排列下第\(j\)個滑動視窗的貢獻

顯然這個東西可以用乘法分配律按照\(j\)分開:$$ans = \sum_ \times (a_j^1 + a_j^2 + ....... + a_j))}$$

對於乙個滑動視窗,在它範圍外的其他格仔不管怎麼變都不會影響它的貢獻,所以這樣的\(a\)是相同的,每種貢獻有\(m^\)個

把相同貢獻的變成乙個,最後變成:$$ans = \sum_^ \times (a_j^1 + a_j^2 + ........ + a_j}))) }$$

發現此時答案為每個滑動視窗單獨的貢獻加起來,而每個滑動視窗的貢獻又相同,所以就等於單個貢獻\(\times\)

\((n-k+1)\)

對單個滑窗期望dp即可,這個複雜度可以是\(o(mlogn)\)或者\(o(nm)\),比較基礎就不寫了(不能理解題解\(o(n^2m)\)的睿智做法

本題難點不在期望dp而在簡化問題(當然像題解一樣直接莽就另當別論了),其實\(m\)可以開到\(10^5\)

#include#define n 505

#define min(x,y) ((x)<(y)?(x):(y))

#define max(x,y) ((x)>(y)?(x):(y))

using namespace std;

typedef long long ll;

const ll mod = 1000000007;

int n,m,k;

ll a[n],f[n][n],sum[n][n];

template void read(t &x)

ll quickpow(ll a,ll b)

return ret;

}int main()

} ll ans=0;

for(int i=1;i<=m;++i) ans=(ans + f[k][i]*a[i]%mod)%mod;

cout<<(ans*(n-k+1)%mod+mod)%mod

}

CSP校內集訓 reverse(數字DP)

給乙個範圍 l,r 求滿足 l leq n leq r 且 l leq rev n leq r 的 n 的個數,其中 rev n 表示將 n 翻轉 123 321 多組詢問 l,r leq 2 64 1 長這樣的計數問題,沒什麼懸念考慮數字dp 只設 f 表示處理到第 i 位是否頂上界似乎不太夠,因...

CSP校內集訓 打撲克

有 n 堆大小為1的撲克,支援合併兩堆撲克和查詢有多少對撲克堆滿足 size i size j leq c c 不確定 暴力做法 開桶記錄當前存在有多少個大小為 i 的堆,查詢可用樹狀陣列或者雙指標,時間複雜度 o m 2logn 或者 o m 2 優化 發現列舉大小的桶有很多是空的,實際上,可以證...

CSP校內集訓 替換遊戲(tarjan 離散化)

給乙個範圍 0,n 有兩種變換方式,k 或者給定的 m 個 x y 但必須保證變換前後的數始終在範圍內,給乙個數 x 求出它一直變換下去 注意不能得到了乙個數之後返回上一步 可以得到的所有數的和的最大值 n leq 10 8 m leq 10 5 k leq n 多組詢問 對兩種方式建邊,顯然乙個強...