題目大意:
有 \(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 ...