#include <bits/stdc++.h> #define MAX_N 1000 using namespace std; int v[MAX_N],w[MAX_N]; int dp[100][100]; int n; int wmax,vmax; int main() { //输入 cin>>n; for(int i=0;i<n;i++){ cin>>w[i]>>v[i]; } cin>>wmax; /*确定子问题: 目的是得到最大价值,操作是要不要把第i件物品放到背包中? */ /*确定dp[][]含义: dp[i][j]: i:前i件物品参与了操作; j:体积为j的背包; dp[][]:在ij情况下的最大价值 ==:前i件中若干个物品放入体积为j的背包中的最大价值。 */ /*调整初始状态:(边界处理) x为任意有效值 dp[0][x] = 0; //前0个物品放入最大支持x的背包中总价值永远是0 dp[x][0] = 0; //背包大小为0,总价值永远为0; */ /*最激动人心的地方:状态转移方程的确定 1.同调整初始状态 2. 如果:背包体积j小于前i个物体之和 背包装不下第i个物体了,此时总价值仍然为j-1时的价值 否则:{ //为了体积V的背包中物体总价值最大化, //第i件应该放入背包中吗? max(不放第i件,放第i件但是有空间减小的代价) //正是因为空间减小了,才能找到以前的值,才能比较 } 代码实现: if( j < w[i] ){ f[i][j] = f[i-1][j]; } else { f[i][j] = max( f[i-1][j] , f[i-1][j-w[i]]+v[i] ); } */ //刚出生哦 /*//初始化的时候已经全部为0,不用再次操作 for(int i = 0;i<n;i++){ dp[i][0]=0; dp[0][i]=0; }*/ //人家dp超简单的 for(int i = 0;i<n;i++){ for(int j = 0;j<=wmax;j++){ if( j<w[i] ){ dp[i+1][j] = dp[i][j]; } else{ dp[i+1][j] = max(dp[i][j],dp[i][j-w[i]]+v[i]); } } } //输出记忆化数组,这里为了输出多一点数据 int print_max = wmax>n ? wmax+1 : n+1; for(int i = 0;i<print_max;i++){ for(int j = 0;j<print_max;j++) cout<<dp[i][j]<<" "; cout<<endl; } cout<<dp[n][wmax]<<endl; //拓展:如果实现输出选择哪一个,把max()函数展开成一个if()即可; return 0; } /** n个物品,重量用w表示,价值用v表示, 从中挑选总重量不大于wmax的物品, 求能挑出的最大值vmax; */ /* data: 4 2 3 1 2 3 4 2 2 5 print: 7 */
【菜鸟er】动态规划_01背包
猜你喜欢
转载自blog.csdn.net/F_zmmfs/article/details/79978494
今日推荐
周排行