贪心算法练习题:部分背包问题
2014-07-28 19:06
567 查看
/*----------------------------------------------------- 有n个物体,第i个物体的重量是wi,价值为vi, 选若干个物体,使得在总重量不超过c的情况下让总价值尽量高。 这里每个物体都可以只取走一部分,价值和重量按比例计算。 输入: 第一行输入两个整数表示n和c。 第2到第n+1行每行两个整数分别表示wi和vi。 输出: 第一行输出所选物品的总价值v和总重量w以及所选物品的种类数num。两两之间用空格分隔。 第二行到第n+1行按照输入物品的顺序输出每种物品被选择的重量。(不被选择的输出0) 思路: 这个题目应该综合考虑重量和价值两个因素,所以要计算出每一种物体 单位重量的价值price,然后按照price从大到小排序。 贪心选择的策略:优先选择price比较大的那种物体。 除了最后一个物体之外,每种物体要么全部选,要么全部不选。 最后一个被选中的物体可能限于总重量C的大小,只能选一部分。 -------------------------------------------------------*/
#include<stdio.h> #include<stdlib.h> struct obj { int weight; int value; int id; double price;//表示该物体单位重量的价值。 int select;//表示该物体被选中的数量 }; void merge_sort1(struct obj *A,int x,int y,struct obj *T);//采用归并排序对A数组排序。按struct obj的price从大到小排序。 void merge_sort2(struct obj *A,int x,int y,struct obj *T);//采用归并排序对A数组排序。按struct obj的id从小到大排序。 int cmp1(struct obj a,struct obj b);//按struct obj的price比较a和b的大小 int cmp2(struct obj a,struct obj b);//按struct obj的id比较a和b的大小 int cmpQsort1(const void *a,const void *b);//按struct obj的price比较a和b的大小 int cmpQsort2(const void *a,const void *b);//按struct obj的id比较a和b的大小 int main() { int n,c,i; long w,num; double v; int t; struct obj *a,*temp; freopen("5.in","r",stdin); scanf("%d %d",&n,&c); a=(struct obj*)malloc(sizeof(struct obj)*n); temp=(struct obj*)malloc(sizeof(struct obj)*n); for(i=0;i<n;i++) { scanf("%d%d",&a[i].weight,&a[i].value); a[i].id=i+1; a[i].price=a[i].value*1.0/a[i].weight; a[i].select=0; } qsort(a,n,sizeof(struct obj),cmpQsort1); //merge_sort1(a,0,n,temp);//按单位重量的价值price排序 /*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); printf("\n"); merge_sort2(a,0,n,temp);//按id排序 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);*/ v=0; //所选择的物体总价值 w=0; //所选择的物体总重量 num=0; //所选择的物体个数 for(i=0;i<n;i++) { w=w+a[i].weight; v=v+a[i].value; a[i].select=a[i].weight; num++; if(w>=c) { if(w==c) { break; } else { t=w-c; v=v-a[i].value*1.0/a[i].weight*t; w=c; a[i].select=a[i].select-t; break; } } } qsort(a,n,sizeof(struct obj),cmpQsort2); //merge_sort2(a,0,n,temp);//按id排序 printf("%.2lf %ld %ld\n",v,w,num); for(i=0;i<n;i++) { printf("%d\n",a[i].select); //printf("%-3d %-3d %-3d %-10.3lf %d\n",a[i].value,a[i].weight,a[i].id,a[i].price,a[i].select); } free(a); free(temp); return 0; } void merge_sort1(struct obj *A,int x,int y,struct obj *T) {//采用归并排序对A数组排序。按struct obj的weight从大到小排序。 if(y-x>1) { int m=x+(y-x)/2; //划分 int p=x,q=m,i=x; merge_sort1(A,x,m,T); merge_sort1(A,m,y,T); while(p<m||q<y) { //if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++]; if(q>=y||(p<m&&A[p].price>=A[q].price)) T[i++]=A[p++]; //if(q>=y||(p<m&&cmp1(A[p],A[q])==1)) T[i++]=A[p++]; else T[i++]=A[q++]; } for(i=x;i<y;i++) A[i]=T[i]; } } void merge_sort2(struct obj *A,int x,int y,struct obj *T) {//采用归并排序对A数组排序。按struct obj的id从小到大排序。 if(y-x>1) { int m=x+(y-x)/2; //划分 int p=x,q=m,i=x; merge_sort2(A,x,m,T); merge_sort2(A,m,y,T); while(p<m||q<y) { //if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++]; if(q>=y||(p<m&& A[p].id<=A[q].id)) T[i++]=A[p++]; //if(q>=y||(p<m&&cmp2(A[p],A[q])==-1)) T[i++]=A[p++]; else T[i++]=A[q++]; } for(i=x;i<y;i++) A[i]=T[i]; } } int cmp1(struct obj a,struct obj b) {//按struct obj的price比较a和b的大小 if(a.price>b.price) return 1; else if(a.price<b.price) return -1; else return 0; } int cmp2(struct obj a,struct obj b) {//按struct obj的id比较a和b的大小 if(a.id>b.id) return 1; else if(a.id<b.id) return -1; else return 0; } int cmpQsort1(const void *a,const void *b) {//按struct obj的price比较a和b的大小 int t=((struct obj *)b)->price-((struct obj *)a)->price; if(t>0) return 1; else if(t<0) return -1; else return 0; } int cmpQsort2(const void *a,const void *b) {//按struct obj的id比较a和b的大小 int t=((struct obj *)a)->id-((struct obj *)b)->id; if(t>0) return 1; else if(t<0) return -1; else return 0; }
View Code
运行案例:
输入:
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
相关文章推荐
- 经典算法6:贪心算法解决部分背包问题
- 贪心算法——部分背包问题(贪心策略内容)
- 部分背包问题的贪心算法正确性证明
- 贪心算法解决部分背包问题
- 贪心算法;部分背包问题;快速排序O(nlgn);贪心算法O(n);
- 部分背包问题的贪心算法正确性证明
- 算法学习:贪心解部分背包问题
- 贪心算法解决部分背包问题(C语言,ruby)
- 【算法】贪心策略实现部分背包问题
- 贪心算法解决部分背包问题 在O(lgn)时间内
- 用贪心算法解决背包问题
- 贪心算法运用于(0/1)背包问题
- 部分背包问题(贪心)
- 贪心算法 - 背包问题
- 纯C语言:贪心部分背包问题源码
- 贪心算法解决背包问题
- 背包问题的贪心算法
- 步步为营(五)贪心(4)部分背包问题
- 数据结构与算法学习之路:背包问题的贪心算法和动态规划算法
- 【算法】贪心算法之背包与装箱问题