傳送門 to loj
不妨分成兩部分討論:x
<
nx<\sqrt
x和 x≥n
x\ge\sqrt n
x≥n
。為啥要這麼分啊?這確實很難說。但是我們可以猜到,我們在讓這兩個值拿到平衡:值的種類和最多選取的個數。
當值的種類很少時,直接多重揹包就行了。當選取的種類很少時呢?用 f(x
,i
)f(x,i)
f(x,i)
表示,選取 i
ii 個不小於 n
\sqrt
n的數,使得其和為 x
xx ,數字的順序不考慮。這個是很經典的問題,可以視作拼出乙個階梯型圖案,一排一排的消除。所以有轉移
f (x
,i)=
f(x−
n,i−
1)+f
(x−i
,i
)f(x,i)=f(x-\sqrt,i-1)+f(x-i,i)
f(x,i)
=f(x
−n,
i−1)
+f(x
−i,i
)然後兩邊都是 o(n
32
)\mathcal o(n^})
o(n23
) 的,拼在一起就可以了。
#include
#include
#include
#include
using
namespace std;
typedef
long
long int_;
inline
intreadint()
inline
intqkpow
(int_ b,int_ q,
int mod)
const
int maxn =
100001
;const
int sqrt =
330;
const
int mod =
23333333
;int dp[sqrt]
[maxn]
;// 揹包
int f[sqrt]
[maxn]
;// f[i][j]: j 分成 i 個數
intmain()
f[0][
0]=1
;// 啥子都沒有
for(
int j=
1; j++j)
for(
int i=j*sqrt; i<=n;
++i)
f[j]
[i]=
(f[j-1]
[i-sqrt]
+ f[j]
[i-j]
)% mod;
int ans =0;
for(
int i=
0; i<=n;
++i)
printf
("%d\n"
,ans)
;return0;
}
loj6089 小 Y 的揹包計數問題
link 好吧開學了果然忙得要死 不過為了證明我的blog還沒有涼,還是跑來更一波水題 有n種物品,第i種體積為i,問裝滿乙個大小為n的揹包有多少種方案?n leq 10 5.這種題一看就很想按根號分類是不是 設閾值大小為 m sqrt n 對於體積 leq m 的所有物品,直接跑多重揹包 f i ...
loj6089 小Y的揹包計數問題
小 y 有乙個大小為 n 的揹包,並且小 y 有 n 種物品。對於第 i 種物品,共有 i 個可以使用,並且對於每乙個 i 物品,體積均為 i 求小 y 把該揹包裝滿的方案數為多少,答案對於 23333333 取模。定義兩種不同的方案為 當且僅當至少存在一種物品的使用數量不同。這個揹包問題讓我耳目一...
LOJ6089 小Y的揹包計數問題
小 y 有乙個大小為 n 的揹包,並且小 y 有 n 種物品。對於第 i 種物品,共有 i 個可以使用,並且對於每乙個 i 物品,體積均為 i 求小 y 把該揹包裝滿的方案數為多少,答案對於 23333333 取模。定義兩種不同的方案為 當且僅當至少存在一種物品的使用數量不同。第一行乙個整數 n 輸...