洛谷P4141 消失之物 題解 揹包問題擴充套件

2022-05-19 22:07:29 字數 1198 閱讀 6591

題目大意:

有 \(n\) 件物品,求第 \(i\) 件物品不能選的時候(\(i\) 從 \(1\) 到 \(n\))0-1揹包方案數。

解題思路:

遍歷每一遍不選的物品,然後對剩餘的物品求01揹包方案數。

時間複雜度為 \(o(n^2m)\) 。

由於這裡每一件物品的價值和時間相同,

所以可以定義狀態 \(f[i]\) 表示填滿體積 \(i\) 的方案數。

則有狀態轉移方程:

\(f[0] = 1\)

\(f[i] = \sum f[i-c]\) (其中 \(c\) 對應每一件物品的體積)

實現**如下:

#include using namespace std;

const int maxn = 2020;

int n, v, w[maxn], f[maxn];

void pack(int c)

void solve(int id)

for (int i = 1; i <= v; i ++) cout << f[i];

cout << endl;

}int main()

**自 kelin大神的部落格

其實只要跑一次揹包(全部物品都在)

然後我們考慮少了某個物品怎麼辦?

我們在01揹包dp時會用到這個轉移

for(int j=m;j>=w[i];--j)

f[j]+=f[j-w[i]];

我們少了i物品就是在原來的基礎上少了一次這樣的轉移

所以我們在原來的基礎上順推減去這樣的一次轉移就ok了

memcpy(g,f,sizeof f);

for(int j=w[i];j<=m;++j)

g[j]-=g[j-w[i]];

實現**如下:

#include using namespace std;

const int maxn = 2020;

int n, v, w[maxn], f[maxn], g[maxn];

void pack(int c)

void unpack(int c)

void init()

}void solve(int id)

int main()

洛谷P4141 消失之物 揹包DP

暴力 暴力列舉少了哪個,下面套乙個01揹包 f i j 表示到了i物品,用了j容量的揹包時的方案數,f i j f i 1 j f i 1 j w i o n 3 優化 不考慮消失的,先跑乙個01揹包,定義g i j 表示i消失時,容量為j的方案數,g i j f n j 不合法的 逆著過來就是g ...

P4141 消失之物

ftiasch 有 n 個物品,體積分別是 w1,w2,wn。由於她的疏忽,第 i 個物 品丟失了。要使用剩下的 n 1 物品裝滿容積為 x 的揹包,有幾種方法 呢?這是經典的問題了。她把答案記為 count i,x 想要得到所有1 i n,1 x m的 count i,x n,m 3000 題解 ...

消失之物 揹包回退

題目鏈結 我們知道 01 揹包方案數的遞推式長這樣 f j f j w i 如果一件物品不選,就會少一次這樣的轉移貢獻。於是我們把這個貢獻還回去。g j g j w i 就做完了。include include include includeusing namespace std define n ...