這種比較特殊的01揹包
01揹包
01揹包
還是沒有做到過唉。。
這道題我們觀察資料,發現v
iv_i
vi的具體數字很小,但是揹包的花費卻很大,我們可以考慮用另外一張方式進行揹包:用價值作為狀態,用花費作為具體的dpdp
dp值進行計算。
求在體積限制為代價最大,等價於在相同的價值**積最小:即用最小的體積買到最大的代價。
為了更加方便統計答案,我們對這些店進行排序:按照每一家店的時間來進行排序。
我們設f[i
][j]
f[i][j]
f[i][j
]表示前i家店,購買出價值為j
jj的最小花費,轉移和正常的01揹包相似:
f [i
][j]
=min
(f[i
−1][
j],f
[i−v
[i]]
+c[i
])f[i][j]=min(f[i-1][j],f[i-v[i]]+c[i])
f[i][j
]=mi
n(f[
i−1]
[j],
f[i−
v[i]
]+c[
i])v[i
]v[i]
v[i]
表示價值,c[i
]c[i]
c[i]
表示花費。
這一步完成後,我們再改變一下狀態:
那麼最後的步驟,我們可以使用兩邊二分查詢來進行:
這種方法十分巧妙,有兩個程式。第乙個是使用stl
stlst
l的,第二個是手寫二分答案的。
**1:
#include
using
namespace std;
int n,m;
int t[
301]
;int v[
301]
;long
long c[
301]
;long
long f[
301]
[90001];
void
sort
(void
)return;}
intmain
(void
)for
(int i=
1;i<=n;
++i)
for(
int j=v-
1;j>=0;
--j)
f[i]
[j]=
min(f[i]
[j+1
], f[i]
[j])
;//f[i][j] 表示 前i件物品 價值至少為j的最小代價
for(
int i=
1,t,m;i<=m;
++i)
return0;
}
**2:
#include
using
namespace std;
int n,m;
int t[
301]
;int v[
301]
;long
long c[
301]
;long
long f[
301]
[90001];
void
sort
(void
)return;}
intfind
(int x)
if(x >= t[r]
)return r;
else
return l;
}int
find2
(int t,
int x)
if(x >=
f(r)
)return r;
else
return l;
}int
main
(void
)for
(int i=
1;i<=n;
++i)
for(
int j=v-
1;j>=0;
--j)
f[i]
[j]=
min(f[i]
[j+1
], f[i]
[j])
;//f[i][j] 表示 前i件物品 價值至少為j的最小代價
for(
int i=
1,t,m;i<=m;
++i)
return0;
}
動態規劃 01揹包
最優二叉查詢樹.cpp 定義控制台應用程式的入口點。01揹包問題。include stdafx.h include include define n 3 the number of real node define m 10 using namespace std int tmain int arg...
01揹包動態規劃
0 1揹包 問題描述 乙個旅行者有乙個最多能用 m公斤的揹包,現在有 n件物品,它們的重量 分別是w1,w2 wn,它們的價值分別為 c1,c2,cn.若每種物品只有一 件求旅行者能獲得最大總價值。輸入格式 w 第一行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 w第2.n 1 行...
0 1揹包(動態規劃)
題意 有n件物品和乙個容量為v的揹包。第i件物品的體積是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。基本思路 這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 即f i v 表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程...