HDU 2546 饭卡 (0/1背包问题)

来源:互联网 发布:c语言从1加到100 编辑:程序博客网 时间:2024/05/29 11:54

饭卡

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7572    Accepted Submission(s): 2582


Problem Description

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

Input

多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。

n=0表示数据结束。

 Output

对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额.

Sample Input

1505101 2 3 2 1 1 2 3 2 1500

Sample Output

-4532

 


 

import java.io.*;import java.util.*;public class Main {int M = 1005, n, m, k;int dp[] = new int[M];public static void main(String[] args) {new Main().work();}void work() {Scanner sc = new Scanner(new BufferedInputStream(System.in));while (sc.hasNext()) {n = sc.nextInt();if(n==0)System.exit(0);Node[] node = new Node[n];Arrays.fill(dp,0);for (int i = 0; i < n; i++) {node[i] = new Node();node[i].a = sc.nextInt();}m = sc.nextInt();if (m < 5)System.out.println(m);else {m=m-5;//预留出5元钱购买价格最大的菜Arrays.sort(node);//从小到大排序,用剩下的钱去购买剩下的菜for (int i = 0; i <n-1; i++) {for(int j=m;j>=0;j--){if(j>=node[i].a)dp[j]=Math.max(dp[j],dp[j-node[i].a]+node[i].a);//花掉的钱}}int last=5-node[n-1].a;//用预留出5元钱购买价格最大的菜System.out.println(m+last-dp[m]);}}}class Node implements Comparable<Node> {int a;public int compareTo(Node o) {return this.a > o.a ? 1 : -1;}}}

原创粉丝点击