作為提高組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])
}int
main()
因為每一行只能選乙個,所以我們可以每行爆搜找選哪個(或者不選),隨後判斷行不行
這道題一拿到題就覺得是dpdp
dp,但是沒想出來轉移方程,想要拿到64分,我們需要把m
mm=2,3的情況拆成兩種來討論,當m=2
m=2m=
2時,用f[i
][j]
[k
]f[i][j][k]
f[i][j
][k]
表示第i
ii行,第一種食材用了j
jj次,第二種用了k
kk次,可以顯然得到乙個轉移方程f[i
][j]
[k]=
su
mf[i][j][k]=sum\
f[i][j
][k]
=sum
當m =3
m=3m=
3時就是四位dpdp
dp
if
(m==2)
rep(i,
1,n)
ans=
(ans+f[n]
[i][i]
)%mod;
printf
("%lld\n"
,ans);}
if(m==3)
rep(i,
0,n)
rep(j,
0,n)
rep(k,
0,n)
printf
("%lld\n"
,ans)
;}
我們換一種想法,我們把所有可能的情況先算出來,然後再把不符合條件的都減去,怎麼算減去的呢,我們可以想到超過一半的只可能有一種菜,我們先迴圈那種菜再第幾列(col),其他的看成一種菜,那麼我們設計狀態f[i
][j]
[k
]f[i][j][k]
f[i][j
][k]
表示前i
ii道菜,超過一半的菜有j
jj道,剩下的選了k
kk道,那麼轉移方程就是f[i
][j]
[k]=
su
mf[i][j][k]=sum\
f[i][j
][k]
=sum
ans=1;
rep(i,
1,n)
rep(col,
1,m)
rep(i,
0,n)
rep(j,
0,n)
}printf
("%lld\n"
,(ans-
1+mod)
%mod)
;
我們發現,我們最後統計的時候是和j
jj,k
kk沒有關係的,我們只要知道他們的差就可以了,所以我們可以優化掉一維,複雜度變成了o(n
2m
)o(n^2m)
o(n2m)
,可以過啦!
轉移就變成了f[i
][j]
=sum
f[i][j]=sum\
f[i][j
]=su
m但是第二維有可能是負的,所以要整體平移
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# define rep(i,a,b) for(int i=a;i<=b;i++)
# define _rep(i,a,b) for(int i=a;i>=b;i--)
using
namespace std;
const
int n=
5e3+5;
const
int zero=
110;
const
int mod=
998244353
;typedef
long
long ll;
template
<
typename t>
void
read
(t &x)
int n,m;
int a[n]
[n];
ll f[45]
[45][
45],g[45][
45][45
][45]
,s[n]
,h[45][
45][45
],dp[zero][2
*zero+10]
;int cnt[n]
,tot;
ll ans;
void
dfs(
int u,ll plus)
dfs(u+
1,plus)
;rep
(i,1
,m)if
(a[u]
[i])
}int
main()
rep(col,
1,m)
rep(i,
1,n)ans=
(ans-dp[n]
[i+zero]
+mod)
%mod;
}printf
("%lld\n"
,(ans-
1+mod)
%mod)
;return0;
}
這道題其實64分不難,但是我特別的菜只打了暴力,所以只有32。。。
所以要好好練一練dpdp
dp
CSP2019 Emiya 家今天的飯
題面 luogu 題解 容斥 dp 首先題意是這樣的 給乙個 n times m 的矩陣,每一行只能選乙個,每一列選的總數不能超過選的總數的一半。求總方案數 考慮容斥 總方案數減去不合法方案數 總方案數顯然 設每一行的總數為 sum i ans prod sum i 1 1 減一是因為不能不做乙個菜...
CSP2019 Emiya 家今天的飯
鏈結 顯然根據性質最多的菜品不超過總數量的一半,可以考慮補集轉化 即計算有乙個菜品超過數量一半的方案數,再用總方案數減 總方案數顯然可以乙個揹包搞定 然而我去年就是因為總方案數沒求對掛了 然後考慮求超過一半的方案數 列舉當前哪個菜品是超過一半的 有乙個顯然的dp f 表示當前到第i行最多的菜品選了j...
csp2019 Emiya家今天的飯題解
qwq 由於窩太菜了,實在是不會,所以在題解的幫助下過掉了這道題。寫此部落格來整理一下思路 傳送簡化一下題意 現在有 n 行 m 列數,選 k 個數的合法方案需滿足 1.一行最多選乙個 2.一列最多選 lfloor frac rfloor 個數 當然,如果你在某一行裡選了0,就相當於沒有在這一行裡選...