WUSTOJ 1320: 饭卡(Java)动态规划-背包
题目链接:🔗1320: 饭卡
参考:🔗hdu 2546 饭卡(经典dp)——H2oooooooooooooooooo
Description
武汉科技大学南苑食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
Input
第一行为T,表示数据组数(1<=T<=100)
对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
接着为n个正整数,表示每种菜的价格。价格不超过50。
然后为一个正整数m,表示卡上的余额。m<=1000。
Output
对于每组输入,输出一行,格式为:Case x: y
x表示测试数据的编号,从1开始。y表示卡上可能的最小余额。
Sample Input
3
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
2
3 2
4
Sample Output
Case 1: -45
Case 2: 32
Case 3: 4
分析💬
背包问题已经接触过几次了。但是这道题目稍稍变化了一点点。当然这也是本题的关键点。
假设我们现在正在买最后一道菜,那么怎样使得最后的余额最少呢?
首先这个菜要最贵,这样才余额才最少。其次我们买之前余额也要尽量少。但是不能低于5元,否则无法购买。
如果 m 小于5的话,那就直接输出,一道菜都不能买。注意编号也要输出。
如果 m 大于5的话,我们只要存5元,然后用剩余的钱,在剩余的 (n - 1) 道菜中买的越多越好。
因此最终问题变成了:我有 (m - 5) 元,买 (n - 1) 道菜,怎样才能总消费最大化?这不就成了很容易的动态规划了吗?
代码
/**
* Time 334ms
* @author wowpH
* @version 1.1
* @date 2019年6月23日上午11:59:50
* Environment: Windows 10
* IDE Version: Eclipse 2019-3
* JDK Version: JDK1.8.0_112
*/
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(new InputStreamReader(System.in));
int[] price, total;// 菜的价值,总消费
int T, n, m;// 数据组数,菜的数量,卡的余额
T = sc.nextInt();
// 要输出测试数据编号k
for (int k = 1; k <= T; ++k) {
n = sc.nextInt();
price = new int[n + 1];// 下标从1开始
for (int i = 1; i <= n; ++i) {
price[i] = sc.nextInt();
}
Arrays.sort(price, 1, n + 1);// 按照价格排序
m = sc.nextInt();
if (m < 5) {
System.out.println("Case " + k + ": " + m);// 不足5元,直接输出
continue;
}
m -= 5;// 至少要留5元,先减掉,到后面再加上来
total = new int[m + 1];// 下标从1开始
int temp;
for (int i = 1; i < n; ++i) {// 前面n-1个菜
for (int j = m; j >= price[i]; --j) {
// 购买第i个菜后的总消费
temp = total[j - price[i]] + price[i];
// 总消费取“不购买”和“购买”第i个菜后较大的情况
total[j] = Math.max(total[j], temp);
}
}
System.out.print("Case " + k + ": ");// 测试数据编号
// 加上保存的5元,再减去前面n-1个菜的总消费,再减去第n个菜的价格
System.out.println(m + 5 - total[m] - price[n]);
}
sc.close();
}
}
需要注意的是别忘了在最后加上5元。
版权声明
- 转载、参考、引用必须在首页添加如下文字:
[WUSTOJ 1320: 饭卡(Java)动态规划-背包——wowpH](https://blog.csdn.net/pfdvnah/article/details/93385427)
- 代码原创,公开引用不能删除首行注释(作者,版本号,时间等信息);
- 如果有疑问欢迎评论区留言,尽量解答;
- 如果有错误,还望大侠评论区指正。