动态规划解决0
假设(X1,X2,…,Xn)是01背包问题的最优解,则有(X2,X3,…,Xn)是其子问题的最优解,
假设(Y2,Y3,…,Yn)是上述问题的子问题最优解,则理应有(V2Y2+V3Y3+…+VnYn)+V1X1 > (V2X2+V3X3+…+VnXn)+V1X1;
而(V2X2+V3X3+…+VnXn)+V1X1=(V1X1+V2X2+…+VnXn),则有(V2Y2+V3Y3+…+VnYn)+V1X1 > (V1X1+V2X2+…+VnXn);
该式子说明(X1,Y2,Y3,…,Yn)才是该01背包问题的最优解,这与最开始的假设(X1,X2,…,Xn)是01背包问题的最优解相矛盾,故01背包问题满足最优性原理;
寻找递推关系式,面对当前商品有两种可能性:第一,包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);
第二,还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i)但价值增加了v(i);
由此可以得出递推关系式:
1) j<w(i) V(i,j)=V(i-1,j)
2) j>=w(i) V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }
#include<bits/stdc++.h> #define CAP 1500 #define NUM 50 using namespace std; int w[NUM]; int v[NUM]; int p[NUM][CAP]; void knapsack(int c,int n) { int jMax=min(w[n]-1,c); for(int j=0;j<=jMax;j++) p[n][j]=0; for(int j=w[n];j<=c;j++) { p[n][j]=v[n]; //cout<<p[n][j]<<endl; } for(int i=n-1;i>1;i--) { jMax=min(w[i]-1,c); for(int j=0;j<=jMax;j++) p[i][j]=p[i+1][j]; for(int j=w[i];j<=c;j++) p[i][j]=max(p[i+1][j],p[i+1][j-w[i]]+v[i]); } p[1][c]=p[2][c]; if(c>w[1]) p[1][c]=max(p[1][c],p[2][c-w[1]]+v[1]); } void traceback(int c,int n,int x[]) { for(int i=1;i<n;i++) { if(p[i][c]==p[i+1][c]) x[i]=0; else { x[i]=1; c=c-w[i]; } x[n]=(p[n][c])?1:0; } } int main() { int c,n; cin>>c>>n; int x[n]; for(int i=1;i<=n;i++) cin>>w[i]>>v[i]; knapsack(c,n); cout<<p[1][c]<<endl; traceback(c,n,x); for(int i=1;i<=n;i++) cout<<x[i]<<" "; }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758相关知识
算法(七)100个经典的动态规划方程
最少费用购物 动态规划
摆花 (DP动态规划)
动态规划 摆花 题解
【动态规划】摆花
花店橱窗布置(洛谷P1854)(动态规划)
动态规划之摆放花束
经典算法动态规划之商品最优购买问题
[动态规划]花店橱窗布置
礼物·动态规划
网址: 动态规划解决0 https://www.huajiangbk.com/newsview1123928.html
上一篇: 28年是什么婚 结婚纪念日庆祝方 |
下一篇: 长辈结婚纪念日祝福语大全 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039