CSP S 2019 Emiya 家今天的飯

2022-06-06 14:27:10 字數 1004 閱讀 9296

loj 3211

看到題目中要求每種主要食材至多在一半的菜中被使用,容易想到補集轉換。

即\(ans=\)總方案數-存在某一種食材在一半以上的菜中被使用的方案。

總方案數很容易求:即對於每一種烹飪方法選至多一道菜的方案為\(s_i+1\),其中\(s_i=\sum_^ a_\)。

故總方案數\(=\prod_^ (s_i+1)-1\),其中-1是因為要去掉一道菜都沒有選的方案。

而不合法的方案,我們可以先欽定第\(w\)列中選出了一半以上的數,於是可以用\(f_\)表示前\(i\)行中已經在第\(w\)列選了\(j\)個數,在其他列選了\(k\)個數的方案。於是有:

\[f_=f_+a_*f_+(s_i-a_)*f_

\]於是答案就是所有滿足\(j>k\)的\(f_\)的和,可以$o(mn^3)做。

考慮優化,事實上我們一直只關心\(j-k\)的大小,於是可以將狀態改為\(f_\)表示前\(i\)行中,第\(w\)列比其他列多選\(j\)個數的方案。於是有:

\[f_=f_+a_*f_+(s_i-a_)*f_

\]於是答案就是\(\sum_^ f_\),就可以\(o(mn^2)\)完成,可以通過此題。

為了防止出現負數下標,可以將下標整體加\(n\)

#include#includeconst int mod=998244353;

const int n=210;

int a[n][2010],s[n],tot=1,bad,n,m,f[n][n];

int add(int x,int y)

int dec(int x,int y)

int main()

for(int w=1;w<=m;++w)

} for(int i=n+1;i<=n+n;++i)tot=dec(tot,f[n][i]);

} printf("%d\n",dec(tot,1));

return 0;

}

CSP S 2019 Emiya 家今天的飯

類似 烏龜棋 的思想,由於 64pts 的 m 3 非常小。我們可以設乙個 dp 建立 m 個維度存下每種物品選了幾次 狀態轉移 根據題意,每種烹飪方法最多選一道菜。答案 sum sum sum f n a b c max a,b,c lfloor a b c 2 rfloor 且 a b c 0 ...

CSP S2019 Emiya 家今天的飯 題解

csp s2 2019 d2t1 很不錯的一題dp,通過這道題學到了很多。身為乙個對dp一竅不通的蒟蒻,在考場上還掙扎了1h來推式子,居然還有幾次幾乎推出正解,然而最後還是只能打個32分的暴搜滾粗 題意分析 給出乙個矩陣,要求每行只能選乙個節點,每列選的節點不能超過所有選的節點的一半,不能不選,給出...

csp2019 Emiya家今天的飯

作為提高組d2t 1d2t1 d2t1 比去年難 所以這道題我打的特別的差 這道題我們很顯然可以看到可以打乙個暴力 複雜度o n n o n n o n n 我考場上就達到了這裡 我太菜了 void dfs int u,ll plus dfs u 1,plus rep i,1 m if a u i ...