贪心算法

概述

求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临着多种选择。对于许多最优化问题,使用动态规划算法来求解有些杀鸡用牛刀了,可以使用更简单,更高效的贪心算法。
贪心算法在每一步都作出当前看起来最佳的选择,也就是说,他总是做出局部最优的选择,寄希望这样的选择能导致全局最优解,即,贪心算法并不保证能得到最优解。

区间贪心(活动选择问题)

方案一

按活动的结束时间递增排序,每次选择结束时间最早的活动。

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
	static int n;
	static LinkedList<Activity>A;
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		n=in.nextInt();
		Activity act[]=new Activity[n];
		A=new LinkedList<>();
		for(int i=0;i<n;i++) {
			act[i]=new Activity(in.nextInt(),in.nextInt

(),in.nextInt());
		}
		Arrays.sort(act, new Comparator<Activity>() {
			@Override
			public int compare(Activity a1,Activity a2) 

{
				if(a1.finish>a2.finish)
					return 1;
				else
					return -1;
			}
		});//升序
		//输出排序之后的活动
		System.out.printf("i ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].num);
		}
		System.out.println();
		System.out.printf("s[i] ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].start);
		}
		System.out.println();
		System.out.printf("f[i] ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].finish);
		}
		System.out.println();
		Greedy(act);//调用贪心算法
		while(!A.isEmpty()) {
			System.out.println(A.pop().num);
		}
	}

	private static void Greedy(Activity[] act) {
		A.add(act[0]);
		int k=0;
		for(int m=1;m<n;m++) {
			if(act[m].start>=act[k].finish) {
				A.add(act[m]);
				k=m;
			}
		}
	}
}
class Activity{
	int num;
	int start;
	int finish;
	public Activity(int num,int start,int finish) {
		this.num=num;
		this.start=start;
		this.finish=finish;
	}
	
}

方案二

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
	static int n;
	static LinkedList<Activity>A;
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		n=in.nextInt();
		Activity act[]=new Activity[n];
		A=new LinkedList<>();
		for(int i=0;i<n;i++) {
			act[i]=new Activity(in.nextInt(),in.nextInt

(),in.nextInt());
		}
		Arrays.sort(act, new Comparator<Activity>() {
			@Override
			public int compare(Activity a1,Activity a2) 

{
				if(a1.start<a2.start)
					return 1;
				else
					return -1;
			}
		});//降序
		//输出排序之后的活动
		System.out.printf("i ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].num);
		}
		System.out.println();
		System.out.printf("s[i] ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].start);
		}
		System.out.println();
		System.out.printf("f[i] ");
		for(int i=0;i<n;i++) {
			System.out.printf("%d ",act[i].finish);
		}
		System.out.println();
		Greedy(act);//调用贪心算法
		while(!A.isEmpty()) {
			System.out.println(A.pop().num);
		}
	}

	private static void Greedy(Activity[] act) {
		A.add(act[0]);
		int k=0;
		for(int m=1;m<n;m++) {
			if(act[m].finish<=act[k].start) {
				A.add(act[m]);
				k=m;
			}
		}
	}
}
class Activity{
	int num;
	int start;
	int finish;
	public Activity(int num,int start,int finish) {
		this.num=num;
		this.start=start;
		this.finish=finish;
	}
}

简单贪心(最大利润问题)

import java.util.*;
public class Main {
    static class mooncakes{
        int totalPrice;
        int amount;
        double unitPrice;
    }//类
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int need = scanner.nextInt();
        mooncakes[] moon = new mooncakes[n];
        for(int i=0;i<n;i++){
            moon[i] = new mooncakes();
            moon[i].amount = scanner.nextInt();
        }
        for(int i=0;i<n;i++){
            moon[i].totalPrice = scanner.nextInt();
            moon[i].unitPrice = (double)moon[i].totalPrice/moon

[i].amount;
        }
        Arrays.sort(moon, new Comparator<mooncakes>() {
            @Override
            public int compare(mooncakes o1, mooncakes o2) {
                if(o1.unitPrice<o2.unitPrice) return 1;
                else return -1;
            }
        });//降序
        double sum=0;
        for(int i=0;i<n;i++){
            if(moon[i].amount<need){   //供不应球,继续下一种
                sum+=moon[i].totalPrice;
                need-=moon[i].amount;
            }
            else{    //需求在此终止
                sum+=moon[i].unitPrice*need;
                break;
            }
        }
        System.out.format("%.2f",sum);
    }
}

Huffman编码

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {

	private static LinkedList<HufNode> hufList = new 

LinkedList<HufNode>();// 容器存放节点值

	class HufNode implements Comparable<HufNode> {
		int value;
		String name;
		HufNode Lchild = null;
		HufNode Rchild = null;

		public HufNode() {

		}

		public HufNode(String s, int v) {
			name = s;
			value = v;
		}

		public HufNode(HufNode l, HufNode r) {
			Lchild = l;
			Rchild = r;
			value = Lchild.value + Rchild.value;

		}

		@Override
		public int compareTo(HufNode node1) {
			if (value < node1.value) {
				return -1;
			} else if (value == node1.value) {
				return 0;
			} else {
				return 1;
			}
		}
	}

	// 哈夫曼编码
	public static void HufmanCode() {
		if (hufList.size() == 1) {
			return;
		}
		while (hufList.size() > 1) {
			Collections.sort(hufList);
			HufNode node = new Main().new 

HufNode(hufList.get(0), hufList.get(1));
			hufList.remove();
			hufList.remove();
			hufList.add(node);
		} // 此时hufList中只有一个元素,这就是编码后的哈夫曼

树的根节点
	}

	// 解码,后序遍历
	public static void decode(HufNode n, String code) {
		if ((n.Lchild == null) && (n.Rchild == null)) {
			System.out.print("元素值为 " + n.name + " 

  编码为:" + code);
			System.out.println();
			return;
		}
		decode(n.Lchild, code + "0");
		decode(n.Rchild, code + "1");
		return;
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		for (int i = 0; i < n; i++) {
			hufList.add(new Main().new HufNode

(in.next(), in.nextInt()));
		}
		HufmanCode();
		decode(hufList.get(0), "");
	}
}

经典背包问题

分数背包问题(贪心算法求解)

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		Goods goods[]=new Goods[n];
		for(int i=0;i<n;i++) {
			goods[i]=new Goods();
			goods[i].weight=in.nextInt();
		}
		for(int i=0;i<n;i++) {
			goods[i].value=in.nextInt();
			goods[i].price=goods[i].value/goods

[i].weight;
		}
		Arrays.sort(goods, new Comparator<Goods>() {
			public int compare(Goods g1,Goods g2) {
				if(g1.price<g2.price) return 1;
				else return -1;
			}
		});
		int w=50;
		double sum=0;
		for(int i=0;i<n;i++){
            if(goods[i].weight<w){   //供不应球,继续下一种
                sum+=goods[i].value;
                w-=goods[i].weight;
            }
            else{    //需求在此终止
                sum+=goods[i].price*w;
                break;
            }
        }
        System.out.format("%.2f",sum);	
	}
}
class Goods{
	int weight,value;
	float price;

}

0-1背包问题(只能用动态规划解决,贪心算法不能得到最优解)

import java.util.Scanner;
public class Main{
	static int n,W;
	static int w[];
	static int c[];
	static int maxn=0;
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		n=in.nextInt();
		W=in.nextInt();
		w=new int[n];
		c=new int[n];
		for(int i=0;i<n;i++)
			w[i]=in.nextInt();
		for(int i=0;i<n;i++)
			c[i]=in.nextInt();
		dp(0,0,0);
		System.out.println(maxn);
		
	}
	private static void dp(int index, int sumw, int sumc) {
		if(index+1==n) 
			return;
		else {
			dp(index+1,sumw,sumc);
			if(sumw+w[index+1]<=W) {
				if(sumc+c[index+1]>maxn) {
					maxn=sumc+c[index+1];//优化
				}
				dp(index+1,sumw+w[index+1],sumc+c[index+1]);
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值