nyoj106 背包问题

微笑背包问题

时间限制: 3000 ms  |           内存限制: 65535 KB
难度: 3
描述
现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10);如果给你一个背包它能容纳的重量为m(10<=m<=20),你所要做的就是把物品装到背包里,使背包里的物品的价值总和最大。
输入
第一行输入一个正整数n(1<=n<=5),表示有n组测试数据;
随后有n测试数据,每组测试数据的第一行有两个正整数s,m(1<=s<=10);s表示有s个物品。接下来的s行每行有两个正整数v,w。
输出
输出每组测试数据中背包内的物品的价值和,每次输出占一行。
样例输入
1
3 15
5 10
2 8
3 9
样例输出
65

应用贪心算法。这个题目已经告诉你单位价值了,所以不需要考虑计算单位价值最高的,从高到低的选择了。我们现在所需要做的就是对单位价值进行排序,然后从高到底取物品,直到重量达到题目中告诉的背包的W。

sort排序,结构体或者二维数组进行储存数据。最后执行计算价值和,不过值得留意就是那个对结构体数据的交换,不用单独定义一个变量,而是用结构体中最后一个多余的进行储存,这是一个小妙招!贪心算法,求局部的最优解,需要看清的是每个(物品的单位重量的价值v和重量w)

法一:
 
 2 #include<stdio.h>
 3 struct wupin
 4 {
 5     int a;
 6     int b;
 7 }wu[11];
 8 int main()
 9 {   
10     int i,j,l,n,s,m,x,q;
11     scanf("%d",&n);
12     while(n--)
13     {
14         scanf("%d%d",&s,&m);
15         for(i=0;i<s;i++)
16             scanf("%d%d",&wu[i].a,&wu[i].b);
17         for(i=0;i<s-1;i++)
18         {
19                 for(j=0;j<s-i-1;j++)
20                 if(wu[j].a>wu[j+1].a)
21                 {
22                     wu[10]=wu[j];
23                     wu[j]=wu[j+1];
24                     wu[j+1]=wu[10];
25                 }//此处就是进行结构体交换的地方,利用最后一个多余的结构体储存。
26         }
27         if(wu[s-1].b>=m)
28             printf("%d\n",m*wu[s-1].a);
29         else
30         {
31             int sum=0,k=0;
32             for(i=s-1;i>=0;i--)
33             {
34                 sum+=wu[i].b;k+=wu[i].a*wu[i].b;//进行计算。
35                 if(m<=sum)
36                 {k-=(sum-m)*wu[i].a;break;}              
37             }
38             printf("%d\n",k);
39         }
40     }return 0;
41 }        
 法二:
1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 struct bb//**定义一个背包的结构体**//
 5 {
 6     int jz;//**价值**//
 7     int zl;//**重量**//
 8 }w[100];
 9 bool comp(bb x,bb y)//**将价值高的排前**//
10 {
11      if(x.jz>y.jz) return true;
12      return false; 
13 }
14 int main()
15 {
16     int s,n,m,i,j,jzsum,zlsum,sum;
17     scanf("%d",&s);
18     while(s--)
19     {
20         jzsum=0;zlsum=0;//**价值的总和****重量的总和**//
21         scanf("%d %d",&n,&m);
22         for(i=0;i<n;i++)
23         {
24             scanf("%d %d",&w[i].jz,&w[i].zl);
25         }
26         sort(w,w+n,comp);
27         for(i=0;i<n;i++)
28         {
29             zlsum=zlsum+w[i].zl;
30             if(zlsum<=m)//**如果背包的容量大于等于全部物品的重量和**//
31             {
32                 jzsum=jzsum+w[i].jz*w[i].zl;
33             }
34             if(zlsum>m)//**如果背包的容量小于全部物品的重量和**//
35             {
36                 sum=m-(zlsum-w[i].zl);//**把多出物品的重量减去**//
37                 jzsum=jzsum+sum*w[i].jz;
38                 break;
39             }
40         }
41         printf("%d\n",jzsum);
42     }
43     return 0;
44 }        
背包问题其实并不难,就是求局部最优解,明了题目的目的就好办了,是个很有特点的算法
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值