贪心算法的设计与实现“背包问题+活动安排”

贪心法基本思想

求解最优化问题的贪心算法包含一系列步骤。每一步都在一组选择中做出在当前看 来最好的选择,希望通过做出局部优化选择达到全局优化选择。但贪心算法不一定总产 生优化解,所以一个贪心算法是否产生优化解,需要严格证明。

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值