Java实现 蓝桥杯VIP 算法提高 邮票面值设计

算法提高 邮票面值设计
时间限制:1.0s 内存限制:256.0MB
问题描述
  给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1~MAX之间的每一个邮资值都能得到。

例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分);如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大值,所以MAX=7,面值分别为1分、3分。
输入格式
  一行,两个数N、K
输出格式
  两行,第一行升序输出设计的邮票面值,第二行输出“MAX=xx”(不含引号),其中xx为所求的能得到的连续邮资最大值。
样例输入
3 2
样例输出
1 3
MAX=7


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Scanner {
	BufferedReader br;
	StringTokenizer st;
	InputStream in = System.in;

	public Scanner() {
		br = new BufferedReader(new InputStreamReader(in));
		eat("");
	}

	private void eat(String s) {
		st = new StringTokenizer(s);
	}

	public String nextLine() {
		try {
			return br.readLine();
		} catch (IOException e) {
			return null;
		}
	}

	public boolean hasNext() {
		while (!st.hasMoreTokens()) {
			String s = nextLine();
			if (s == null)
				return false;
			eat(s);
		}
		return true;
	}

	public String next() {
		hasNext();
		return st.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

	public float nextFloat() {
		return Float.parseFloat(next());
	}

	public Double nextDouble() {
		return Double.parseDouble(next());
	}
	
	public Long nextLong(){
		return Long.parseLong(next());
	}
}

public class youpiaomianzhisheji {
    static int N, K;
    static int count[] = new int[11];
    static int sum[] = new int[11];
    static int Value[] = new int[1000];

    public static void main(String[] args) {
        Scanner in = new Scanner();
        N = in.nextInt();
        K = in.nextInt();
        count[1] = 1; //1是固定的
        Dp(1);
        for (int i = 1; i <= K; i++) {
            System.out.print(sum[i] + " ");
        }
        System.out.println();
        System.out.print("MAX=" + (sum[0] - 1));
    }

    private static void Dp(int dp) {
        int x = getbig(dp);
        if (dp == K) {
            return;
        }
        for (int i = x; i > count[dp]; i--) {
            count[dp + 1] = i;
            Dp(dp + 1);
        }
    }

    private static int getbig(int dp) {
        for (int i = 1; i <= 1000; i++) {
            Value[i] = 1000;
            for (int j = 1; j <= dp; j++)
                if (i >= count[j]) {
                    Value[i] = Math.min(Value[i], Value[i - count[j]] + 1);
                }
            if (Value[i] > N) {
                if (i > sum[0]) {
                    sum[0] = i;
                    for (int j = 1; j <= dp; ++j)
                        sum[j] = count[j];
                }
                return i;
            }
        }
        return 0;
    }
}

原文地址:https://www.cnblogs.com/a1439775520/p/13078793.html