LOJ6089 小 Y 的揹包計數問題

2021-10-24 22:05:16 字數 1585 閱讀 8392

傳送門 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 輸...