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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

NOIP2019 Emiya家今天的饭

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOIP2019 Emiya家今天的饭 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

NOIP2019 Emiya家今天的飯

ACM退役選手遠程口胡
csf如今真的是太菜了,最后16分的做法愣是想了一下午
考慮使用容斥方法:

1

采用動態規劃,先求出在無限制情況下,安排kkk種烹飪方法總的方案數.
dp2[i][j]dp2[i][j]dp2[i][j]表示已經考慮完前iii種烹飪方法,共做了jjj個菜的方案數.
那么顯然,決策分2種情況,用或不用第iii種烹飪方法,用的話就只能選一種主要食材.
dp2[i][j]=dp2[i?1][j]+dp2[i?1][j?1]?(∑t=1ma[i][t])dp2[i][j]=dp2[i-1][j] + dp2[i-1][j-1]*(\sum_{t=1}^m a[i][t])dp2[i][j]=dp2[i?1][j]+dp2[i?1][j?1]?(t=1m?a[i][t])
時間復雜度O(n2)O(n^2)O(n2),∑t=1ma[i][t]\sum_{t=1}^m a[i][t]t=1m?a[i][t]可以提前維護好.

2

采用動態規劃,計算出那些不合法的方案,并將這些方案減掉.
因為每次只能有一個主要食材不合法.所以對每個主要食材單獨考慮,假設當前ttt食材不合法了.
最樸素的想法是,采用dp1[i][j][k]dp1[i][j][k]dp1[i][j][k]表示考慮完前iii烹飪方法,已經做了jjj個菜,使用ttt食材的有kkk個的方案數.

那么,決策就是第iii中烹飪方案選不選,選了之后,選不選ttt作為食材,一共333個轉移.

記錄linesum[i]=∑t=1ma[i][t]linesum[i]=\sum_{t=1}^m a[i][t]linesum[i]=t=1m?a[i][t]

dp1[i][j][k]=dp1[i?1][j][k]+dp1[i?1][j?1][k?1]?a[i][t]+dp1[i?1][j?1][k]?(linesum[i]?a[i][t])dp1[i][j][k]=dp1[i-1][j][k]+dp1[i-1][j-1][k-1]*a[i][t]+dp1[i-1][j-1][k]*(linesum[i]-a[i][t])dp1[i][j][k]=dp1[i?1][j][k]+dp1[i?1][j?1][k?1]?a[i][t]+dp1[i?1][j?1][k]?(linesum[i]?a[i][t])

最后答案減去dp1[n][j][k]∣k>j/2dp1[n][j][k]|_{k \gt j/2}dp1[n][j][k]k>j/2?

時間復雜度為O(n3m)O(n^3m)O(n3m),只能過84分,接下來繼續優化

事實上,我們無需同時記錄jjjkkk,而只需要記錄k?(j?k)k - (j-k)k?(j?k)的值就足夠了,也就是ttt食材的數量和非ttt食材的數量.

這樣的話,記錄dp1[i][Δ]dp1[i][\Delta]dp1[i][Δ]表示考慮完前iii行,選取的ttt食材和非ttt食材的差值為Δ\DeltaΔ時候,方案數.
轉移方程如下
dp1[i][Δ]=dp1[i?1][Δ]+dp1[i?1][Δ?1]?a[i][t]+dp1[i?1][Δ+1]?(linesum[i]?a[i][t])dp1[i][\Delta]=dp1[i-1][\Delta] + dp1[i-1][\Delta-1]*a[i][t]+dp1[i-1][\Delta+1]*(linesum[i]-a[i][t])dp1[i][Δ]=dp1[i?1][Δ]+dp1[i?1][Δ?1]?a[i][t]+dp1[i?1][Δ+1]?(linesum[i]?a[i][t])
最后答案減去dp1[n][Δ]∣Δ>0dp1[n][\Delta]|_{\Delta>0}dp1[n][Δ]Δ>0?
時間復雜度O(n2m)O(n^2m)O(n2m)

綜上,總的時間復雜度O(n2m)O(n^2m)O(n2m)

AC代碼

#include <iostream> #include <cstring> using namespace std; #define int long long const int MOD = 998244353; const int maxn = 107,maxm = 2007; int dp1[maxn][2*maxn]; // int dp2[maxn][maxn]; int linesum[maxn]; //s1表示 int a[maxn][maxm]; int n, m; signed main() {cin >> n >> m;for(int i = 1;i <= n;++i) {for(int j = 1;j <= m;++j) {cin >> a[i][j];a[i][j] %= MOD;linesum[i] = ( linesum[i] + a[i][j] ) % MOD;}}int ans = 0;for(int t = 1;t <= m;++t) {memset(dp1,0,sizeof(dp1));dp1[0][0 + 100] = 1;for(int i = 1;i <= n;++i) {for(int j = -i + 100;j <= i + 100;++j) {dp1[i][j] = dp1[i-1][j];dp1[i][j] += (dp1[i-1][j-1] * a[i][t]) % MOD;//取dp1[i][j] += (dp1[i-1][j+1] * ((linesum[i] - a[i][t] + MOD) % MOD)) % MOD;//不取dp1[i][j] %= MOD;}}for(int j = 1;j <= n;++j) {ans = (ans - dp1[n][j + 100]) % MOD;}}dp2[0][0] = 1;for(int i = 1;i <= n;++i) {for(int j = 0;j <= i;++j) {dp2[i][j] = dp2[i-1][j];for(int k = 1;k <= m;++k) {dp2[i][j] += dp2[i-1][j-1] * a[i][k] % MOD;dp2[i][j] %= MOD;}}}for(int j = 1;j <= n;++j)ans = (ans + dp2[n][j]) % MOD;cout << ans << endl;return 0; }

總結

以上是生活随笔為你收集整理的NOIP2019 Emiya家今天的饭的全部內容,希望文章能夠幫你解決所遇到的問題。

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