贪心法基本思想
求解最优化问题的贪心算法包含一系列步骤。每一步都在一组选择中做出在当前看 来最好的选择,希望通过做出局部优化选择达到全局优化选择。但贪心算法不一定总产 生优化解,所以一个贪心算法是否产生优化解,需要严格证明。
1.用贪心策略设计与实现一个贪心算法,求解 背包问题(非0-1背包)
背包问题描述:给定 n 种物品和一个背包,物品 i 的重量是 w[i], 其价值是 p[i], 背包的容量为 C。设物品已按单位重量价值递减的次序排序。每种物品不可以装入背包多次,但可以装入部分的物品 i。背包问题是选择装入背包中的物品,在不超过背包容量的前提下使背包的得总价值最大。
用户需要输入物品的数量、各个物品的重量以及价
值。程序应该给出良好的用户界面显示出(输出)装入背包中的物品相关信息,包括:
每个装包物品价格、装入比例,以及装入背包中物品的总价值。
代码实现
#include <stdio.h>
float Knapsack(int n,float M,float v[],float w[],float x[]);
int main()
{
int M,N;
float w[20]={0};
float v[20]={0};
float x[20]={0};
float V=0;
printf("背包所能容纳的重量为:");
scanf("%d",&M);
printf("待装物品的数量:");
scanf("%d",&N);
for(int i=0;i<N;i++){
printf("第%d个物品的重量和价值为:",i+1);
scanf("%f %f",&w[i],&v[i]);
printf("\n");
}
V=Knapsack(N,M,v,w,x);
printf("选择装下的物品比例如下:\n");
for(int i=0; i<=N; i++) {
printf("[%d]:%.2f\n",i,x[i]);
}
printf("背包中装入的总价值为%.2f",V);
return 0;
}
float Knapsack(int n,float M,float v[],float w[],float x[]){
//Sort(n,v,w);
float c=M;
float V=0;
int i;
for (i=0;i<n;i++) {
if (w[i]>c) {
break;
}
x[i]=1;
c-=w[i];
V+=v[i];
}
if (i<=n) {
x[i]=c/w[i];
V+=x[i]*v[i];
c=0;
}
return V;
}
2. 假设活动已经按照结束时间递增的次序排序。用贪心策略设计与实现一个贪心算法,求解活动安排问题
活动安排问题描述:用户需要输入活动个数 n,以及每个活动的开始时间与结束时间,程序应该给出良好的用户界面,输出被安排(即被选中)的活动有关信息,包括:被选中活动号、开始时间、结束时间。
代码实现
#include<stdio.h>
void greedySelect(int n, int s[], int f[], bool A[]){
A[1] = true;
int j = 1;
for(int i = 2; i <= n; i++){
if(s[i] >= f[j]){
A[i] = true;
j = i;
}
else{
A[i] = false;
}
}
}
int main(){
int s[20] = {0};
int f[20] = {0};
bool A[20];
int N;
printf("待选择的活动有多少个?");
scanf("%d",&N);
printf("请输入每个活动的开始和结束时间:\n\n");
for(int i = 1; i <= N; i++ ) {
printf("第%d个活动的开始时间和结束时间:",i);
scanf("%d %d",&s[i],&f[i]);
}
greedySelect(N, s, f, A);
printf("最大相容活动子集:\n");
for(int i = 1; i <= N; i++){
if(A[i]){
printf("[%d]: <%d,%d>\n",i,s[i],f[i]);
}
}
return 0;
}