常用算法案例之贪心法(C语言)

1. 背包问题

#include "stdafx.h"
#include <stdio.h>
#include "malloc.h"
//最大单位重量价值先放背包原则

float * GreedyKnapsack(int n, int W, int *Weights, float *Values, float *VW) {

	int i;
	//分配空间及初始化 
	float *x = (float *)malloc(sizeof(float)*n);
	for (i = 0; i<n; i++)
		x[i] = 0;
	for (i = 0; i<n; i++)
		if (Weights[i] <= W) {          //如果背包剩余容量可以装下该物品
			x[i] = 1;
            printf("背包%d 减去重量%d \n", W,Weights[i] );
			W = W - Weights[i];
			
		}
		else
			break;
	if (i<n) {
		x[i] = W / (float)Weights[i];     //如果还有物品可以部分装入背包中
	}

	for (i = 0; i<n; i++)   //输出
		printf ("%f \n",x[i] );
	return x;
}

int main(int argc, const char * argv[]) {

	int Weights[5] = { 30, 10, 20, 50, 40 };
	float Values[5] = { 65, 20, 30, 60, 40 };
	float VW[5] = { 2.1,2,1.5,1.2,1 };
	float x[5];
	GreedyKnapsack(5, 100,  Weights,  Values,  VW);
	while (1);
	return 0;
}

 

 

 

2.钱币找零

#include<iostream>
#include<algorithm>
#include "stdafx.h"
using namespace std;
const int N = 7;
int Count[N] = { 3,0,2,1,0,3,5 };//每一张纸币的数量 
int Value[N] = { 1,2,5,10,20,50,100 };//每一张的面额  
static int min(int a, int b)
{
	return a>=b ? b : a;

}

int solve(int money)
{
	printf("金额%d \n", money);
	int num = 0;
	for (int i = N - 1; i >= 0; i--)            //1.排序,从大到小
	{

		int c = min(money / Value[i], Count[i]);//2.约束条件每一个所需要的张数 
		
		money = money - c*Value[i]; 
		num += c;                               //总张数 
		printf("剩余金额 %d 面值%d 张数%d\n", money,Value[i],c);
	}
	if (money>0) num = -1;
	return num;
}


int main()
{
	int money = 325;
	int res = solve(money);
	while (1);
}

3.活动安排

#include "stdafx.h"
#include<stdio.h>
#define n 11
int s[n + 1] = { -1,1,3,0,5,3,5,6,8,8,2,12 };                                                 //活动按结束的时间递增排列
int f[n + 1] = { 0,4,5,6,7,8,9,10,11,12,13,14 };
//递归法
int RECURSIVE_ACTIVITY_SELECTOR(int *s,int *f,int i,int j)         //S[i][j]是所有与a[i],a[j]兼容的活动,f[i]是活动i的结束时间,i,n是下标,s[i]表示i活动开始的时间
{	
    int m = i+1 ;                               
	while (m <= n && s[m] < f[i])                                     //这里一开始i=1的话m=2 在比较s[2]和f[1]就会漏掉一个,所以把主函数里面i的位置都减掉一
	{
		m = m + 1;

	}
	if (m <= n)
	{
		printf("递归a[%d]   ", m);
        
        int rt=RECURSIVE_ACTIVITY_SELECTOR(s, f, m, n);
        printf("----\n");
		return rt;

	}
	else
		return 0;
}
//迭代
int GREEDY_ACTIVITY_SELECTOR(int *s, int *f)
{
	
	int i = 1,m;
	printf("贪心a[%d]", 1);           //前面有推论结束时间最早的一个一定是最大活动里面的一个选择,结束时间按递增排序,所以a1一定会被输出
	for (m = 2; m <= n; m++)
	{
		if (s[m] >= f[i])
		{
			printf("a[%d]    ", m);
			i = m;                              //每次递归或者迭代都是在上一次调用的结束时间基础上选择下一次调用的开始时间
		}

	}
	return 0;
}

int main()
{
    //递归法
	RECURSIVE_ACTIVITY_SELECTOR(s, f, 1-1, n);  
	printf("\n");
    //迭代
	GREEDY_ACTIVITY_SELECTOR(s, f);
    while(1);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值