loj6089 小Y的揹包計數問題

2022-05-08 01:06:07 字數 1420 閱讀 3730

小\(y\)有乙個大小為\(n\)的揹包,並且小\(y\)有\(n\)種物品。

對於第\(i\)種物品,共有\(i\)個可以使用,並且對於每乙個\(i\)物品,體積均為\(i\)。

求小\(y\)把該揹包裝滿的方案數為多少,答案對於\(23333333\)取模。

定義兩種不同的方案為:當且僅當至少存在一種物品的使用數量不同。

這個揹包問題讓我耳目一新啊。

\(idea\)棒棒的。

注意到題目中物品\(i\)(\(i\geq\sqrt n\))的個數限制實際上是不存在的。

所以可以把這個問題分為兩個子問題:多重揹包問題和完全揹包問題。

設\(f[i][v]\)表示前\(i\)個物品,總體積為\(v\)時的方案數。

對於\(i\leq\sqrt n\):(多重揹包問題)

很顯然有$$f[i][v]=\sum_^if[i-1][v-j*i]$$

可以字首和優化做到\(o(n\sqrt n)\)。

對於\(i\geq\sqrt n\):(完全揹包問題)

又注意到乙個物品最多取\(\sqrt n\)個。

同樣設個\(g[i][v]\)表示方案數。

可以認為我們要\(dp\)出乙個和為\(n\),最小數至少\(\sqrt n+1\)的不下降序列

(序列中的數是物品體積)。

轉移有兩種:

則$$g[i][v]=g[i-1][v-\sqrt n-1]+g[i][v-i]$$

這個複雜度\(o(n)\)?

最後討論一下給前乙個問題分配多少體積,後乙個問題分配多少體積,統計答案即可。

#include#include#include#include#include#include#define ll long long

#define re register

#define il inline

#define max(a,b) (((a)>(b))?(a):(b))

#define min(a,b) (((a)<(b))?(a):(b))

#define fp(i,a,b) for(re int i=a;i<=b;i++)

#define fq(i,a,b) for(re int i=a;i>=b;i--)

using namespace std;

const int n=2005,inf=2e9,mod=23333333;

int n,f[n],g[350][n],s[n],ans=-inf,m;

il ll gi()

int main()

}g[0][0]=1;ans=f[n];

fp(i,1,m)

for(re int j=i*(m+1);j<=n;j++)

printf("%d\n",ans);

return 0;

}

LOJ6089 小 Y 的揹包計數問題

傳送門 to loj 不妨分成兩部分討論 x nx sqrt x和 x n x ge sqrt n x n 為啥要這麼分啊?這確實很難說。但是我們可以猜到,我們在讓這兩個值拿到平衡 值的種類和最多選取的個數。當值的種類很少時,直接多重揹包就行了。當選取的種類很少時呢?用 f x i f x,i f ...

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 取模。定義兩種不同的方案為 當且僅當至少存在一種物品的使用數量不同。第一行乙個整數 n 輸...