连续邮资问题——动态规划+回溯算法

连续邮资问题:
问题表述为:假设国家发行了n种不同面值的邮票,并且规定每张信封上最多只允许贴m张邮票。连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计,在一张信封上可以贴出从邮资1开始,增量为1的最大连续邮资区间。
举例分析:当n=2,m=3时,如果面值分别为1和4,则可以获得的邮资范围为1~6 加上 8 , 9 , 12,则可以获得1~7之间的每个邮资值,并且7就是可以得到的连续的邮资最大值

实现思路为把所有能表示的数值全部进行计算,存入hashmap中去重,再通过自然数的顺序遍历从而进行判断最大的邮资区间,通过比较来判断是否采用本次的结果。

废话不多说,直接上 bug

package test;

import java.util.HashMap;
import java.util.Scanner;

public class Postage {
     
	
	public static int quantity;
	public static int maxQuantity;
	public static int value[];
	public static int maxResult = 0;
	public static int result[];
	
	public static void input() {
     
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入邮票数量:");
		quantity = scan.nextInt();
		System.out.println("请输入最多可用邮票数量:(小于" + quantity + ")");
		maxQuantity = scan.nextInt();
		if(quantity < maxQuantity) {
     
			System.out.println("输入无意义,请重新输入!");
			input();
		}
		value = new int[quantity];
		value[0] = 1;
		result = new int[value.length];
		scan.close();
		System.out.println("--------------------------------邮票初始化完成--------------------------------");
		System.out.println();
	}
	
	public static void postage(int subscript,int minValue,int maxValue) {
     
		if(subscript == quantity - 1) {
     
			if(calc(subscript) > maxResult) {
     
				maxResult = calc(subscript);
				deepCopy();
			}
		}else {
     
			for(int i = minValue;i <= maxValue;i++) {
     
				value[subscript + 1] = i;
				maxValue = calc(subscript + 1) + 1;
				minValue = value[subscript + 1] + 1;
				postage(subscript + 1,minValue,maxValue);
			}		
		}
	}
	
	public static int calc(int subscript) {
     
		HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
		int temp[] = new int[subscript + 1];
		for(int k = 0;k <= subscript;k++) {
     
			temp[k] = value[k];
		}
		temp(0, 0, map, temp);
		for(int k = 4;;k++) {
     
			if(!map.containsKey(k)) {
     
				return k - 1;
			}
		}
	}
	
	public static void temp(int n,int total,HashMap<Integer, Integer> map,int[]temp) {
     	
		if(n <= maxQuantity) {
     
			map.put(total, total);
			for(int k : temp) {
     
				total += k;
				temp(n + 1,total,map,temp);
				total -= k;
			}
		}
	}
	
	public static void deepCopy() {
     
		for(int i = 0;i < value.length;i++) {
     
			result[i] = value[i];
		}
	}
	
	public static void print() {
     
		System.out.println("--------------------------------连续集邮算法完成--------------------------------");
		System.out.println("最大表示范围为1-" + maxResult + "  面值情况如下:");
		for(int temp : result) {
     
			System.out.print("面值为: " + temp + "\t");
		}
	}
	
	public static void main(String[] args) {
     
		input();
		postage(0,2,5);
		print();
	}
	
}

注:其中当可用邮票数量即maxQuantity 大于5时,程序运行时间则会进行陡增。

改进点:all

你可能感兴趣的:(算法,java)