贪心法

算法设计思想

贪心法的基本思想是逐步获得最优解。贪心法在求解最优解的问题时,从最初阶段开始,每一个阶段总是做一个局部最优的贪心选择,不断将问题转化成规模最小的子问题。因此,贪心法并不是从整体最优考虑,它只是在某种程度上的局部最优解。

贪心法有两个最重要的性质:
1.最优子结构的性质:当一个问题的最优解包含子问题的最优解时,称此问题有最优子结构。
2.贪心选择性质


典型例题

一、找零钱问题

某单位给每个员工发工资。为了确保不要临时兑换零钱,且取款的张数最少,取工资前要统计所有员工的工资所需要的各种币值的张数。

import java.util.Scanner;

public class ChangeMoney {

	public static void main(String[] args) {
		System.out.println("请输入员工工资--以0结束:");
		Scanner scanner = new Scanner(System.in);
		Boolean isFlag = true;
		int arr[] = new int[] { 0, 100, 50, 20, 10, 5, 2, 1 };
		int array[] = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
		while (isFlag) {
			int num = scanner.nextInt();
			if (num == 0)
				isFlag = false;
			for (int i = 1; i <= 7; i++) {
				int A = num / arr[i];
				array[i] += A;
				num -= A * arr[i];
			}
		}
		for (int i = 1; i <= 7; i++) {
			System.out.printf("%d------%d\n", arr[i], array[i]);
		}
	}
}
算法优化
import java.util.Scanner;

public class ChangeMoney2 {

	public static void main(String[] args) {
		change();
	}

	private static void change() {
		System.out.println("请输入员工工资--以0结束:");
		Scanner scanner = new Scanner(System.in);
		Boolean isFlag = true;
		int array[] = new int[] { 0, 0, 0, 0, 0, 0, 0 };
		while (isFlag) {
			int num = scanner.nextInt();
			if (num == 0)
				isFlag = false;
			array[0] += num / 100;
			num %= 100;
			array[1] += num / 50;
			num %= 50;
			array[2] += num / 20;
			num %= 20;
			array[3] += num / 10;
			num %= 10;
			array[4] += num / 5;
			num %= 5;
			array[5] += num / 2;
			num %= 2;
			array[6] += num;
		}
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}
}

二、最优装载

有一批集装箱要装上一艘载重量为c的货轮,其中集装箱的重量为w,要求装载体积不受限制的情况下,尽可能的多的集装箱装到货轮上。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Huolun {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("输入集装箱的个数:");
		int num = scanner.nextInt();
		System.out.println("输入最大载重量:");
		int max = scanner.nextInt();
		System.out.println("逐个输入集装箱的重量:");
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 1; i <= num; i++) {
			int number = scanner.nextInt();
			list.add(number);
		}
		Collections.sort(list);
		int count=0;
		for (int i = 0; i <num; i++) {
			count+=list.get(i);
			if (count>= max) {
				for (int j = 0; j <= i-1; j++) {
					System.out.println(list.get(j));
				}
				return;
			}
		}
	}

}

三、哈夫曼编码

import java.util.Scanner;
public class HuffManCode {
	//建立数的节点类
    static class Node{
        int weight;//频数
        int parent;
        int leftChild;
        int rightChild;

        public Node(int weight,int parent,int leftChild,int rightChild){
            this.weight=weight;
            this.parent=parent;
            this.leftChild=leftChild;
            this.rightChild=rightChild;
        }

        void setWeight(int weight){
            this.weight=weight;
        }

        void setParent(int parent){
            this.parent=parent;
        }

        void setLeftChild(int leftChild){
            this.leftChild=leftChild;
        }

        void setRightChild(int rightChild){
            this.rightChild=rightChild;
        }

        int getWeight(){
            return weight;
        }

        int getParent(){
            return parent;
        }

        int getLeftChild(){
            return leftChild;
        }

        int getRightChild(){
            return rightChild;
        }
    }

    //新建哈夫曼编码
    static class NodeCode{
        String character;
        String code;
        NodeCode(String character,String code){
            this.character=character;
            this.code=code;
        }
        NodeCode(String code){
            this.code= code;
        }

        void setCharacter(String character){
            this.character=character;
        }

        void setCode(String code){
            this.code=code;
        }

        String getCharacter(){
            return character;
        }

        String getCode(){
            return code;
        }
    }

    //初始化一个huffuman树
    public static void initHuffmanTree(Node[] huffmanTree,int m){
        for(int i=0;i<m;i++){
            huffmanTree[i] = new Node(0,-1,-1,-1);
        }
    }

    //初始化一个huffmanCode
    public static void initHuffmanCode(NodeCode[] huffmanCode,int n){
        for(int i=0;i<n;i++){
            huffmanCode[i]=new NodeCode("","");
        }
    }

    //获取huffmanCode的符号
    public static void getHuffmanCode(NodeCode[] huffmanCode , int n){
        Scanner input = new Scanner(System.in);
        for(int i=0;i<n;i++){
            String temp = input.next();
            huffmanCode[i] = new NodeCode(temp,"");
        }
    }

    //获取huffman树节点频数
    public static void getHuffmanWeight(Node[] huffmanTree , int n){
        Scanner input = new Scanner(System.in);
        for(int i=0;i<n;i++){
            int temp = input.nextInt();
            huffmanTree[i] = new Node(temp,-1,-1,-1);
        }
    }

    //从n个结点中选取最小的两个结点
    public static int[] selectMin(Node[] huffmanTree ,int n)  
    {  
        int min[] = new int[2];
          class TempNode
           {  
                  int newWeight;//存储权  
                  int place;//存储该结点所在的位置  

                  TempNode(int newWeight,int place){
                      this.newWeight=newWeight;
                      this.place=place;
                  }

                  void setNewWeight(int newWeight){
                      this.newWeight=newWeight;
                  }

                  void setPlace(int place){
                      this.place=place;
                  }

                  int getNewWeight(){
                      return newWeight;
                  }

                  int getPlace(){
                      return place;
                  }
           } 

           TempNode[] tempTree=new TempNode[n];  

         //将huffmanTree中没有双亲的结点存储到tempTree中 
           int i=0,j=0;   
           for(i=0;i<n;i++)  
           {  
                  if(huffmanTree[i].getParent()==-1&& huffmanTree[i].getWeight()!=0)  
                  {  
                      tempTree[j]= new TempNode(huffmanTree[i].getWeight(),i);  
                      j++;  
                  }  
           } 

           int m1,m2;  
           m1=m2=0;  
           for(i=0;i<j;i++)  
           {  
                  if(tempTree[i].getNewWeight()<tempTree[m1].getNewWeight())//此处不让取到相等,是因为结点中有相同权值的时候,m1取最前的   
                         m1=i;  
           }  
           for(i=0;i<j;i++)  
           {  
                  if(m1==m2)  
                         m2++;//当m1在第一个位置的时候,m2向后移一位  
                  if(tempTree[i].getNewWeight()<=tempTree[m2].getNewWeight()&& i!=m1)//此处取到相等,是让在结点中有相同的权值的时候,  

                                       //m2取最后的那个。  
                         m2=i;  
           }  

           min[0]=tempTree[m1].getPlace();  
           min[1]=tempTree[m2].getPlace();  
       return min;
    }  

    //创建huffmanTree
    public static void createHaffmanTree(Node[] huffmanTree,int n){   
           if(n<=1)  
               System.out.println("Parameter Error!");  
           int m = 2*n-1; 
           //initHuffmanTree(huffmanTree,m);  

           for(int i=n;i<m;i++)  
           {      
               int[] min=selectMin(huffmanTree,i);
               int min1=min[0];
               int min2=min[1];
               huffmanTree[min1].setParent(i);  
               huffmanTree[min2].setParent(i);  
               huffmanTree[i].setLeftChild(min1);  
               huffmanTree[i].setRightChild(min2);
               huffmanTree[i].setWeight(huffmanTree[min1].getWeight()+ huffmanTree[min2].getWeight());   
           }  
    }

    //创建huffmanCode
    public static void createHaffmanCode(Node[] huffmanTree,NodeCode[] huffmanCode,int n){
        Scanner input = new Scanner(System.in);
        char[] code = new char[10]; 
        int start;
        int c;
        int parent;
        int temp;

        code[n-1]='0'; 
        for(int i=0;i<n;i++)  
           {
            StringBuffer stringBuffer = new StringBuffer();
            start=n-1;
            c=i;
            while( (parent=huffmanTree[c].getParent()) >=0 )  
                  {  
                         start--;  
                         code[start]=((huffmanTree[parent].getLeftChild()==c)?'0':'1');  
                         c=parent;  

                  } 
            for(;start<n-1;start++){
                 stringBuffer.append(code[start]);
            }
            huffmanCode[i].setCode(stringBuffer.toString());
           }
    }

    //输出hufmanCode
    public static void ouputHaffmanCode(NodeCode[] huffmanCode,int n){
        System.out.println("字符与编码的对应关系如下:");
        for(int i=0;i<n;i++){
            System.out.println(huffmanCode[i].getCharacter()+":"+huffmanCode[i].getCode());
        }
    }

    //主函数
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int n;
        int m;
        System.out.print("请输入字符个数:");
        n = input.nextInt();
        m=2*n-1;
        Node[] huffmanTree = new Node[m];
        NodeCode[] huffmanCode = new NodeCode[n];

        //初始化huffmanTree,huffmanCode
        initHuffmanTree(huffmanTree,m);
        initHuffmanCode(huffmanCode,n);

        //获取huffmanCode的符号
        System.out.print("请输入哈夫曼编码的字符:");
        getHuffmanCode(huffmanCode,n);

        //获取huffmanTree的频数
        System.out.print("请输入哈夫曼编码字符对应的频数:");
        getHuffmanWeight(huffmanTree,n);

        //创建huffmanTree
        createHaffmanTree(huffmanTree,n);
        //创建huffmanCode
        createHaffmanCode(huffmanTree,huffmanCode,n);

        //输出huffmanCode编码
        ouputHaffmanCode(huffmanCode,n);

    }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值