51nod1597 有限揹包計數問題

2021-07-29 18:28:35 字數 1064 閱讀 5353

你有乙個大小為n的揹包,你有n種物品,第i種物品的大小為i,且有i個,求裝滿這個揹包的方案數有多少

兩種方案不同當且僅當存在至少乙個數i滿足第i種物品使用的數量不同

n≤100000,答案模23333333,時限2.333s

這道題一看是一道多重揹包,但是範圍有點大啊。。。

可以嘗試利用一下題目的條件,對於i≤

n√,就做一次多重揹包。合併一種物品時,通過字首和可以優化到o(n)。 對於i

>n√

,可以當成完全揹包來做!

但是直接上完全揹包又很慢。。。

但是可以注意到另一點:這些物品使用個數也不超過n√

,那麼乙個思路出來了:設g[i][j]表示用i個物品,體積為j的方案數。

轉移:g[i

][j]

=g[i

][j−

i]+g

[i−1

][j−

n√−1

] 。第乙個表示把當前i個物品的體積都加1,第二個表示加入乙個體積為n√

+1的物品。由於加入物品的體積是不上公升的,所以是正確的。

時間複雜度o(

nn√)

#include 

#include

#include

using

namespace

std;

const

int n=100005,mo=23333333;

typedef

long

long ll;

int n,g[2][n],p,q,m,f[2][n],s,t,ans;

int main()}}

t=p; ans+=f[t][n];

g[0][0]=1; p=0; q=1;

for (int i=1;i<=m;i++,p^=1,q^=1)

for (int j=0;j<=n;j++) ans=(ans+(ll)f[t][j]*g[q][n-j])%mo;

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

return

0;}

51nod1597 有限揹包計數問題

51nod1597 有限揹包計數問題 試題描述 你有乙個大小為n的揹包,你有n種物品,第i種物品的大小為i,且有i個,求裝滿這個揹包的方案數有多少 兩種方案不同當且僅當存在至少乙個數i滿足第i種物品使用的數量不同 輸入 第一行乙個正整數n 1 n 10 5 輸出 乙個非負整數表示答案,你需要將答案對...

51Nod 1597 有限揹包計數問題

首先這是乙個多重揹包 但是它的資料非常特殊,我們可以利用其性質優化演算法 乙個顯然的優化是 當 i sqrt n 時,可以取消個數限制 設 f i j 表示選了 i 個物品,體積為 j 的方案數 一共有兩種轉移 可以由 i 1 個物品加上乙個最小的物品 sqrt n 1 可以由 i 個物品全部加一 ...

51nod 1597 有限揹包計數問題 dp

你有乙個大小為n的揹包,你有n種物品,第i種物品的大小為i,且有i個,求裝滿這個揹包的方案數有多少 兩種方案不同當且僅當存在至少乙個數i滿足第i種物品使用的數量不同 1 n 10 5,答案對23333333取模 設lim sqrt n 我們把所有物品按照大於lim和不大於lim分成兩部分。對於大於l...