多元Huffman编码问题

算法作业:

当 样例为 7 5 --------- 5 9 12 13 16 22 45的时候那么 最小值应该是148 ,但是如果按照我们的贪心算法是先将最小的情况合并的话 那么就会出错。

合并为 5 9 12 13 16 。。。。。然后 55 + 22 + 45 = 122+55  = 177 那就错了

所以我们改下。。。。5 9 12 先合并为26  然后13 16 22 26 45 再合并就122  结果为122+26 = 148  over

至于最大值就是最大的两个数合并再扔进去即可~~~

 

那么要怎么解决? 我刚开始想着是反着来的,不过后来。。。发现往前面+0即可 就是

编程9 5  ------0 0  5 9 12 13 16 22 45 over  那么就是0 0 5 9 12 = 26   然后13 16 22 26 45----->122  + 26 = 148

over

其实要加的0的个数和n和k之间是有一个关系的不过我懒得算了直接暴力走一趟让它自己算去吧

代码:

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
	private static Scanner sc = new Scanner(System.in); 
	public static void main(String[] args)throws FileNotFoundException{
		try 
		{
			sc = new Scanner(new FileInputStream("E:\\input.txt"));
			PrintStream ps = new PrintStream("E:\\output.txt");
			System.setOut(ps);//把创建的打印输出流赋给系统。即系统下次向 ps输出
			while(sc.hasNext())
			{
				int n = sc.nextInt();
				int k = sc.nextInt();
				int num[] = new int[n];
				for(int i = 0 ; i < n ; i ++)
					num[i] = sc.nextInt();
				int ans1 = getMax(n, k, num);
				int ans2 = getMin(n, k, num);
				System.out.print(ans1 + " " + ans2 + "\n");
			}
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	private static int getMax(int n,int k,int num[])
	{
		Comparator<Integer> cmp = new Comparator<Integer>() { 
			public int compare(Integer e1, Integer e2) {
				return e2 - e1;
			}
		};
		PriorityQueue<Integer> qu = new PriorityQueue<Integer>(cmp);
		for(int i = 0 ; i < n; i ++)
			qu.add(num[i]); //把所有元素都扔进去之后
		int ans = 0 ;
		while(qu.size() > 1) 
		{
			int sum = 0 ;
			sum = qu.poll() + qu.poll();
			ans += sum;
			qu.add(sum);
		}
		return ans;
	}
	private static int getMin(int n, int k,int num[])
	{
		PriorityQueue<Integer> qu = new PriorityQueue<Integer>();
		for(int i = 0; i < n; i ++)
			qu.add(num[i]);
		int m = n;
		while(m > k) {
			m = m - k + 1;
		}//不管输入的如何或者是接下来如何,此刻都是m < k 的
		for(int i = 1; i <= k - m; i++)
			qu.add(0);
		int ans = 0;
		while(qu.size() > 1)
		{
			int sum = 0;
			for(int i = 1; i <= k; i++) 
				sum += qu.poll();
			qu.add(sum);
			ans += sum;
		}
		return ans;
	}
}

 

截图:

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值