其实不要背包理解成DP里非常特殊的,并且和DP有所不同,,,, 其实不然
背包只是DP中的一种而已,,,不要为背包而做背包,,要灵活运用。。。。
说起来惭愧我的水平也不咋滴,正在努力中。。。。
普通背包就只有物品的重量与价值 这里我稍微高点弄的 物品包括个数,重量,体积,价值。
题目来源:国际大学生程序设计竞赛例题解(三)
题目:小明去旅游需要带上一些物品,有5中物品选择,每种物品的体积,重量,数量,价值分别如下:
物品编号 | 体积/cm3 | 重量/kg | 数量/个 | 价值/元 |
1 | 30 | 3 | 10 | 4 |
2 | 50 | 8 | 10 | 5 |
3 | 10 | 2 | 10 | 2 |
4 | 23 | 5 | 8 | 3 |
5 | 130 | 20 | 5 | 11 |
现在限制总的体积最多为500cm3,总的重量最多为100kg,请问小明能带上的物品的最大总价值是多少?
输入数据:
5
30 3 10 4
50 8 10 5
10 2 10 2
23 5 8 3
130 20 5 11
500 100
输出:
72
程序:
上面三维数组,大家应该知道在只有重量和价值的时候二维可以搞成一维的DP 当然这里原理一样 可以搞成二维的
观察看程序 区别 红色文字
#include<iostream>
#include<string.h>
#define maxn 6
using namespace std;
int v[maxn],w[maxn],c[maxn],t[maxn];
int f[6][501][101];
int f2[501][101];//二维
int main()
{
int i,num,maxx,maxy;
cin>>num;
for(i=1;i<=num;i++)
{cin>>v[i]>>w[i]>>c[i]>>t[i];}
cin>>maxx>>maxy;
//先初始解
memset(f,0,sizeof(f));
memset(f2,0,sizeof(f2));
int n,x,y;
for(n=1;n<=num;n++)
for(x=maxx;x>=v[n];x--)
for(y=maxy;y>=w[n];y--)
{
int maxi=c[n];
if(x/v[n]<maxi)maxi=x/v[n];
if(y/w[n]<maxi)maxi=y/w[n];
/*
//①
for(i=1;i<=maxi;i++)
{
f[n][x][y]=f[n-1][x][y];
f[n][x][y]=max(f[n][x][y],f[n-1][x-i*v[n]][y-i*w[n]]+i*t[n]);
}*/
//②
/*
for(i=0;i<=maxi;i++)
{
f[n][x][y]=max(f[n][x][y],f[n-1][x-i*v[n]][y-i*w[n]]+i*t[n]);
}
*/
//上面 ①②两个效果一样的(完全一样) think i=0
//③ 这个是上面版本的空间压缩成二维的了 节省空间了
for(i=1;i<=maxi;i++)
{
f2[x][y]=max(f2[x-i*v[n]][y-i*w[n]]+i*t[n],f2[x][y]);
}
}
/*
int ans=0;
for(x=0;x<=maxx;x++)
for(y=0;y<=maxy;y++)
if(f[num][x][y]>ans)ans=f[num][x][y];
cout<<f[num][maxx][maxy]<<endl;
cout<<ans<<endl;*/
cout<<f2[maxx][maxy]<<endl;
return 0;
}
/*
5
30 3 10 4
50 8 10 5
10 2 10 2
23 5 8 3
130 20 5 11
500 100
5
68 1 14 3
51 12 17 5
55 2 10 3
44 5 11 4
70 22 9 10
500 100
3
3 1 1 2
2 1 1 6
2 1 1 1
5 100
*/
然后我们想怎么样才能输出我的加入背包的是哪些物品呢?就是反着来模拟入背包决策就行。。。。