说良心话,题目不难,但是题目真的很不好懂,解读一下吧
题意:
读入分两行,第一行为邮票面额(面额相同也视为种类不同)以0结束,第二行为顾客要求的面额,以0结束
要求:每个顾客最多拿4张邮票,并求最优解
输出:对于每个顾客要求输出一行
对于最优解的定义:
1.要求邮票种类尽量多(原则上每种邮票可以无限供应)
2.满足条件1的情况下,要求顾客拿到的邮票张数尽量少
3.满足条件2的情况下,要求顾客拿到的邮票中,面额最大的邮票面额越大越好
4.若满足以上3个条件的解不唯一,输出该顾客拿到的邮票种类数,以及“tie”
5.无法满足顾客要求输出“ ---- none”
PS:(聪明人才能看到我给的提示)
bug1,由于poj没有specail judge,面额的拼凑方案必须按从小到大排序
bug2,邮票种类远不止题目中给的25种,数组开小了会RE,建议开大点,第一次开了60都不够,坑爹啊!
1 package poj.ProblemSet; 2 3 import java.util.Scanner; 4 5 public class poj1010 { 6 7 public static final int MAXN = 100; 8 public static int[] stamp_time = new int[MAXN]; 9 public static int[] stamp = new int[MAXN]; 10 public static int[] customer = new int[MAXN]; 11 public static int[] ans = new int[MAXN]; 12 public static int stamp_n, customer_n, flag; 13 public static int ans_type, ans_total_time, ans_max_stamp; 14 public static int now_type, now_total_time, now_max_stamp; 15 16 public static void query() { 17 now_type = now_total_time = now_max_stamp = 0; 18 for (int i = 1; i <= stamp_n; i++) { 19 if (stamp_time[i] > 0) { 20 now_type++; 21 now_total_time += stamp_time[i]; 22 if (stamp[i] > now_max_stamp) 23 now_max_stamp = stamp[i]; 24 } 25 } 26 } 27 28 public static void update(int type) { 29 ans_type = type; 30 ans_total_time = ans_max_stamp = 0; 31 for (int i = 1; i <= stamp_n; i++) { 32 ans[i] = stamp_time[i]; 33 if (ans[i] > 0) { 34 ans_total_time += ans[i]; 35 if (stamp[i] > ans_max_stamp) 36 ans_max_stamp = stamp[i]; 37 } 38 } 39 } 40 41 public static void dfs(int cost, int type, int a, int num) { 42 if (num > 4 || cost < 0) return; 43 if (cost == 0) { 44 if (type > ans_type) { flag = 0;update(type); } 45 else if (type == ans_type) { 46 query(); 47 if (now_total_time < ans_total_time) { flag = 0;update(type); } 48 else if (now_total_time == ans_total_time) { 49 if (now_max_stamp > ans_max_stamp) { flag = 0;update(type); } 50 else if (now_max_stamp == ans_max_stamp) flag = 1; 51 } 52 } 53 54 } 55 for (int i = a; i <= stamp_n; i++) { 56 if (i == a) { 57 if (type == 0) { stamp_time[a]++;dfs(cost - stamp[a], 1, a, num + 1);stamp_time[a]--; } 58 else { stamp_time[a]++;dfs(cost - stamp[a], type, a, num + 1);stamp_time[a]--; } 59 } 60 else { stamp_time[i]++;dfs(cost - stamp[i], type + 1, i, num + 1);stamp_time[i]--; } 61 } 62 } 63 64 public static void main(String[] args) { 65 Scanner cin = new Scanner(System.in); 66 while (cin.hasNext()) { 67 stamp_n = customer_n = 0; 68 for (int i = 0; i < MAXN; i++) stamp_time[i] = stamp[i] = customer[i] = 0; 69 do stamp[++stamp_n] = cin.nextInt(); while (stamp[stamp_n] != 0); 70 do customer[++customer_n] = cin.nextInt(); while (customer[customer_n] != 0); 71 stamp_n--; 72 customer_n--; 73 for (int i = 1; i <= stamp_n; i++) 74 for (int j = i + 1; j <= stamp_n; j++) 75 if (stamp[i] > stamp[j]) { 76 int temp = stamp[i]; 77 stamp[i] = stamp[j]; 78 stamp[j] = temp; 79 } 80 for (int i = 1; i <= customer_n; i++) { 81 ans_type = ans_total_time = ans_max_stamp = flag = 0; 82 for (int j = 0; j < MAXN; j++) ans[j] = 0; 83 dfs(customer[i], 0, 1, 0); 84 if (flag == 1) System.out.println(customer[i] + " (" + ans_type + "): tie"); 85 else if (ans_type > 0) { 86 System.out.print(customer[i] + " (" + ans_type + "):"); 87 for (int j = 1; j <= stamp_n; j++) if (ans[j] > 0) while (ans[j]-- > 0) System.out.print(" " + stamp[j]); 88 System.out.println(); 89 } 90 else System.out.println(customer[i] + " ---- none"); 91 } 92 } 93 } 94 }