再次复习背包。。。

其实不要背包理解成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
*/

 

 

然后我们想怎么样才能输出我的加入背包的是哪些物品呢?就是反着来模拟入背包决策就行。。。。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helihui123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值