原題傳送門
每行最多取乙個告訴我們可以枚舉行
所以這道題目總體複雜度裡肯定有行的複雜度o(n
)o(n)
o(n)
考場上寫的是m=2
/3
m=2/3
m=2/
3的暴力,直接把每一列分別取了幾個寫到狀態裡面去
正解需要考慮正難則反
我們寫直接將每行最多乙個當作大前提
要求的是沒有一列取了超過一半的東西
那麼這個答案其實=所有方案-有一列取了超過一半的方案
這裡就有乙個重要性質:最多只有一列會超過一半(雖然顯然但是我考場上並沒發現)令s
is_i
si表示第i
ii行的和
g i,
jg_
gi,j
表示前i
ii行選了j
jj個的方案數
f i,
jf_
fi,j
表示前i
ii行,超過一半的列比其他所有多j
jj個的方案數
先求g i,
jg_
gi,jgi,
j=gi
−1,j
+si∗
gi−1
,j−1
g_=g_+s_i*g_
gi,j=
gi−1
,j+
si∗
gi−1
,j−1
再求fi,
jf_
fi,j
我這個狀態的設計已經將超過一半的情況表示了出來,但是並沒有表示超過的一半的列是哪一列
但是我們可以列舉超過一半的列,再具體求f
ff,因為列舉的複雜度是o(m
)o(m)
o(m)
,求值的複雜度是o(n
m)
o(nm)
o(nm
),所以,求f
ff陣列的值為本題主要複雜度,o(n
2m
)o(n^2m)
o(n2m)
令第k
kk列選擇的東西超過了一半
f i,
j=fi
−1,j
+ai,
k∗fi
−1,j
−1+(
si−a
i,k)
∗fi−
1,j+
1f_=f_+a_*f_+(s_i-a_)*f_
fi,j=
fi−1
,j+
ai,k
∗fi
−1,j
−1+
(si
−ai,
k)∗
fi−1
,j+1
答案為∑i=
1nfn
,i
\sum_^f_
i=1∑n
fn,i
code:
#include
#define maxn 4010
#define ll long long
using
namespace std;
const ll qy =
998244353
;int n, m;
ll ans, s[maxn]
, f[
110]
[maxn]
, g[maxn]
[maxn]
, a[maxn]
[maxn]
;inline
intread()
intmain()
g[0][
0]=1
;for
(int i =
1; i <= n;
++i)
for(
int j =
0; j <= n;
++j) g[i]
[j]=
(g[i -1]
[j]+
(j ? s[i]
* g[i -1]
[j -1]
% qy :0)
)% qy;
ans =
(-ans + qy)
% qy;
for(
int i =
1; i <= n;
++i)
(ans +
= g[n]
[i])
%= qy;
printf
("%lld\n"
, ans)
;return0;
}
題解 LuoGu2827 蚯蚓
原題傳送門 此題非常優先佇列,非常裸 但是資料規模似乎在暗示我們甚至有o n o n o n 寫法驚訝地發現題目中的乙個隱含性質 先切的蚯蚓一定比對應的後切的蚯蚓長 維護3個佇列,分別表示沒切過,p,1 p p,1 p p,1 p 3組蚯蚓 因為單調,每次比一比隊首彈出,隊尾插入 再是用到乙個思想,...
題解 逐個擊破 luogu2700
現在有n個城市,其中k個被敵方軍團占領了,n個城市間有n 1條公路相連,破壞其中某條公路的代價是已知的。現在,告訴你k個敵方軍團所在的城市,以及所有公路破壞的代價,請你算出花費最少的代價將這k個地方軍團互相隔離開,以便第二步逐個擊破敵人。第一行包含兩個正整數n和k。第二行包含k個整數,表示哪個城市別...
題解 Luogu1453 城市環路
給你一棵樹,強制要求一條邊只能選乙個點,並且還額外給條邊 s t s,t 說s,t也不能同時選,求最大貢獻 這不是擺明了那你用樹形dp切掉的節奏嗎?設f u 0 1 f u 0 1 表示以u u 為根的字樹,u role presentation u u點選或不選的最大貢獻 然後轉移比較顯然,1.如...