贪心算法练习题:部分背包问题

/*-----------------------------------------------------
有n个物体,第i个物体的重量是wi,价值为vi,
选若干个物体,使得在总重量不超过c的情况下让总价值尽量高。
这里每个物体都可以只取走一部分,价值和重量按比例计算。

输入:
第一行输入两个整数表示n和c。
第2到第n+1行每行两个整数分别表示wi和vi。 

输出:
第一行输出所选物品的总价值v和总重量w以及所选物品的种类数num。两两之间用空格分隔。
第二行到第n+1行按照输入物品的顺序输出每种物品被选择的重量。(不被选择的输出0) 

思路:
这个题目应该综合考虑重量和价值两个因素,所以要计算出每一种物体
单位重量的价值price,然后按照price从大到小排序。
贪心选择的策略:优先选择price比较大的那种物体。
除了最后一个物体之外,每种物体要么全部选,要么全部不选。
最后一个被选中的物体可能限于总重量C的大小,只能选一部分。
-------------------------------------------------------*/

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 struct obj
  4 {
  5     int weight;
  6     int value;
  7     int id;
  8     double price;//表示该物体单位重量的价值。
  9     int select;//表示该物体被选中的数量
 10 };
 11
 12 void merge_sort1(struct obj *A,int x,int y,struct obj *T);//采用归并排序对A数组排序。按struct obj的price从大到小排序。
 13 void merge_sort2(struct obj *A,int x,int y,struct obj *T);//采用归并排序对A数组排序。按struct obj的id从小到大排序。
 14
 15 int cmp1(struct obj a,struct obj b);//按struct obj的price比较a和b的大小
 16 int cmp2(struct obj a,struct obj b);//按struct obj的id比较a和b的大小
 17 int cmpQsort1(const void *a,const void *b);//按struct obj的price比较a和b的大小
 18 int cmpQsort2(const void *a,const void *b);//按struct obj的id比较a和b的大小
 19
 20 int main()
 21 {
 22     int n,c,i;
 23     long w,num;
 24     double v;
 25     int t;
 26     struct obj *a,*temp;
 27     freopen("5.in","r",stdin);
 28     scanf("%d %d",&n,&c);
 29     a=(struct obj*)malloc(sizeof(struct obj)*n);
 30     temp=(struct obj*)malloc(sizeof(struct obj)*n);
 31     for(i=0;i<n;i++)
 32     {
 33         scanf("%d%d",&a[i].weight,&a[i].value);
 34         a[i].id=i+1;
 35         a[i].price=a[i].value*1.0/a[i].weight;
 36         a[i].select=0;
 37     }
 38     qsort(a,n,sizeof(struct obj),cmpQsort1);
 39     //merge_sort1(a,0,n,temp);//按单位重量的价值price排序
 40     /*for(i=0;i<n;i++) printf("%-3d %-3d %-3d %-10.3lf\n",a[i].value,a[i].weight,a[i].id,a[i].price);
 41     printf("\n");
 42     merge_sort2(a,0,n,temp);//按id排序
 43     for(i=0;i<n;i++) printf("%-3d %-3d %-3d %-10.3lf\n",a[i].value,a[i].weight,a[i].id,a[i].price);*/
 44
 45     v=0;   //所选择的物体总价值
 46     w=0;   //所选择的物体总重量
 47     num=0; //所选择的物体个数
 48     for(i=0;i<n;i++)
 49     {
 50         w=w+a[i].weight;
 51         v=v+a[i].value;
 52         a[i].select=a[i].weight;
 53         num++;
 54         if(w>=c)
 55         {
 56             if(w==c)
 57             {
 58                 break;
 59             }
 60             else
 61             {
 62                 t=w-c;
 63                 v=v-a[i].value*1.0/a[i].weight*t;
 64                 w=c;
 65                 a[i].select=a[i].select-t;
 66                 break;
 67             }
 68         }
 69     }
 70     qsort(a,n,sizeof(struct obj),cmpQsort2);
 71     //merge_sort2(a,0,n,temp);//按id排序
 72     printf("%.2lf %ld %ld\n",v,w,num);
 73     for(i=0;i<n;i++)
 74     {
 75         printf("%d\n",a[i].select);
 76         //printf("%-3d %-3d %-3d %-10.3lf %d\n",a[i].value,a[i].weight,a[i].id,a[i].price,a[i].select);
 77     }
 78
 79     free(a);
 80     free(temp);
 81     return 0;
 82 }
 83
 84 void merge_sort1(struct obj *A,int x,int y,struct obj *T)
 85 {//采用归并排序对A数组排序。按struct obj的weight从大到小排序。
 86     if(y-x>1)
 87     {
 88         int m=x+(y-x)/2; //划分
 89         int p=x,q=m,i=x;
 90         merge_sort1(A,x,m,T);
 91         merge_sort1(A,m,y,T);
 92         while(p<m||q<y)
 93         {
 94             //if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++];
 95             if(q>=y||(p<m&&A[p].price>=A[q].price)) T[i++]=A[p++];
 96             //if(q>=y||(p<m&&cmp1(A[p],A[q])==1)) T[i++]=A[p++];
 97             else T[i++]=A[q++];
 98         }
 99         for(i=x;i<y;i++) A[i]=T[i];
100     }
101 }
102 void merge_sort2(struct obj *A,int x,int y,struct obj *T)
103 {//采用归并排序对A数组排序。按struct obj的id从小到大排序。
104     if(y-x>1)
105     {
106         int m=x+(y-x)/2; //划分
107         int p=x,q=m,i=x;
108         merge_sort2(A,x,m,T);
109         merge_sort2(A,m,y,T);
110         while(p<m||q<y)
111         {
112             //if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++];
113             if(q>=y||(p<m&& A[p].id<=A[q].id)) T[i++]=A[p++];
114             //if(q>=y||(p<m&&cmp2(A[p],A[q])==-1)) T[i++]=A[p++];
115             else T[i++]=A[q++];
116         }
117         for(i=x;i<y;i++) A[i]=T[i];
118     }
119 }
120 int cmp1(struct obj a,struct obj b)
121 {//按struct obj的price比较a和b的大小
122     if(a.price>b.price) return 1;
123     else if(a.price<b.price) return -1;
124     else return 0;
125 }
126 int cmp2(struct obj a,struct obj b)
127 {//按struct obj的id比较a和b的大小
128     if(a.id>b.id) return 1;
129     else if(a.id<b.id) return -1;
130     else return 0;
131 }
132 int cmpQsort1(const void *a,const void *b)
133 {//按struct obj的price比较a和b的大小
134     int t=((struct obj *)b)->price-((struct obj *)a)->price;
135     if(t>0) return 1;
136     else if(t<0) return -1;
137     else return 0;
138 }
139 int cmpQsort2(const void *a,const void *b)
140 {//按struct obj的id比较a和b的大小
141     int t=((struct obj *)a)->id-((struct obj *)b)->id;
142     if(t>0) return 1;
143     else if(t<0) return -1;
144     else return 0;
145 }

运行案例:

输入:

10 100
20 50
20 30
5 200
25 250
28 28
10 200
3 300
4 200
8 16
9 90

输出:

1330.00 100 9
20
16
5
25
0
10
3
4
8
9

贪心算法练习题:部分背包问题,布布扣,bubuko.com

时间: 2024-10-16 18:30:34

贪心算法练习题:部分背包问题的相关文章

第十六章 贪心算法——0/1背包问题

1.问题描述: 给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题. 2.最优性原理: 设(y1,y2,…,yn)是 (3.4.1)的一个最优解.则(y2,…,yn)是下面相应子问题的一个最优解:

C++贪心算法实现部分背包问题

_(:з」∠)_ 1 #include <cstdio> 2 #include <iostream> 3 #include <ctime> 4 #include <windows.h> 5 #include <algorithm> 6 #include <fstream> 7 using namespace std; 8 struct object 9 { 10 int no; 11 double weight; 12 double

数据结构之贪心算法(背包问题的思考)-(十)

贪心策略.关于贪心算法的思考,思考过程都放在代码中了. package com.lip.datastructure; /** *贪心算法:装箱问题的思考 * @author Lip *装箱问题可以是时间调问题的延伸,当一个箱子没有容积限制,那么就是时间调度问题 *在时间调度问题中:存在两个可以讨论的问题.1.平均最短时间 2.总的最短时间 *这两个问题都和装箱问题中问题如此类似. */ /* * 上面是我理解的装箱问题,本来是想说背包问题的 * 背包问题的描述:有N件物品和一个容量为V的背包.第

Java 算法(一)贪心算法

Java 算法(一)贪心算法 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.贪心算法 什么是贪心算法?是指在对问题进行求解时,总是做出当前看来是最好的选择.也就是说,不从整体最优上加以考虑,所得出的结果仅仅是某种意义上的局部最优解. 因此贪心算法不会对所有问题都能得到整体最优解,但对于很多问题能产生整体最优解或整体最优解的近似解. 贪心算法的构成部分: 候选对象集合 :候选添加进解的对象的结合· 解对象集合 :初始时

贪心算法之背包问题

贪婪算法的基本思想:通过一系列步骤来构造问题的解,每一步都是对已构造的部分解的一个扩展,直到获得问题的完整解. 贪婪算法中,每一步“贪婪地” 选择最好的部分解,但不顾及这样选择对整体的影响(局部最优),因此得到的全局解不一定最好的解,但对许多问题它能产生整体最优解. 具体算法描述: public static void Greedy()        {            float cu = c;            int temp = 0;            int i = 0;

[C++] 贪心算法之活动安排、背包问题

一.贪心算法的基本思想 在求解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解. 从贪心算法的定义可以看出,贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解.如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一. 二.贪心算法的基本要素 (1)最优子结构性质 (2)贪心选择性质(局部最优选择) 三.贪心算法实例 1.活动安排 设有n个活

背包问题:0/1背包问题 普通背包问题(贪心算法只适用于普通背包问题)

//sj和vj分别为第j项物品的体积和价值,W是总体积限制. //V[i,j]表示从前i项{u1,u2,…,un}中取出来的装入体积为j的背包的物品的最大价值. 第一种:0/1背包问题 最大化 ,受限于  1)若i=0或j=0,  V[i,j] = 0 2)若j<si, V[i,j] = V[i-1,j] 3)若i>0且j>=si, V[i,j] = Max{V[i-1,j],V[i-1,j-si]+vi} 第二种:背包问题:在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部

背包问题:动态规划和贪心算法

1. 动态规划 以下关于动态规划的文字描述来源 动态规划之背包问题(一) 作者:Hawstein 出处:http://hawstein.com/posts/dp-knapsack.html 一切都要从一则故事说起. 话说有一哥们去森林里玩发现了一堆宝石,他数了数,一共有n个. 但他身上能装宝石的就只有一个背包,背包的容量为C.这哥们把n个宝石排成一排并编上号: 0,1,2,-,n-1.第i个宝石对应的体积和价值分别为V[i]和W[i] .排好后这哥们开始思考: 背包总共也就只能装下体积为C的东西

部分背包问题的贪心算法正确性证明

一,部分背包问题介绍 首先介绍下0-1背包问题.假设一共有N件物品,第 i 件物品的价值为 Vi ,重量为Wi,一个小偷有一个最多只能装下重量为W的背包,他希望带走的物品越有价值越好,请问:他应该选择哪些物品? 0-1背包问题的特点是:对于某件(更适合的说法是:某类)物品,要么被带走(选择了它),要么不被带走(没有选择它),不存在只带走一部分的情况. 而部分背包问题则是:可以带走一部分.即,部分背包问题可带走的物品 是可以 无限细分的.(连续与离散的区别) 可以把0-1背包问题中的物品想象的一个