小\(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 輸...