Problem Description

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

Input

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

Output

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

Sample Input

1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0

Sample Output

-45
32
解题思路:简单的01背包。只要卡余额不小于5,那么就可以买,很容易就想到背包容量为m-5,只要从这n种白菜中选出总重量不大于m-5并且使得总价值最大,那么应该会使卡上的余额最小,但是提交一发WA,经过分析后发现还缺少条件限制,举个栗子:假设现在卡上有10元,有两种白菜对应的价格分别为5元和6元,根据之前的做法将会得到卡上的余额是5元,事实上还可以购买6元这种白菜,即卡上最终的余额为-1元,原因就是之前的做法中只能挑选5元这种白菜,此时背包容量已满,但是卡上余额还有5元。因此应该考虑留出5元来买最贵的白菜,再从其他n-1种白菜中选取若干种白菜装入背包中使得最终总重量不超过m-5时有最大价值,这就是最优策略。做法:先排序,留5块钱买最贵的菜,再去挑选前n-1种菜使得消费的价格总和不超过m-5元,这样就使得消费最大,对应卡上的余额最少为m-dp[m-5]-vi[n-1]元。
AC代码:
 #include<bits/stdc++.h>
using namespace std;
const int maxn=;
int n,m,vi[maxn],dp[maxn];
int main(){
while(~scanf("%d",&n)&&n){
memset(dp,,sizeof(dp));
memset(vi,,sizeof(vi));
for(int i=;i<n;++i)scanf("%d",&vi[i]);
sort(vi,vi+n);//排序
scanf("%d",&m);
if(m<)printf("%d\n",m);
else{
for(int i=;i<n-;++i)//最后一个菜不挑选,留在最后买
for(int j=m-;j>=vi[i];--j)
dp[j]=max(dp[j],dp[j-vi[i]]+vi[i]);
printf("%d\n",m-dp[m-]-vi[n-]);//减去一个最贵的菜
}
}
return ;
}

题解报告:hdu 2546 饭卡(01背包)的更多相关文章

  1. HDU 2546 饭卡(01背包裸题)

    饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  2. HDU 2546 饭卡(01 背包)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546 思路:需要首先处理一下的的01背包,当饭卡余额大于等于5时,是什么都能买的,所以题目要饭卡余额最小, ...

  3. HDU -2546饭卡(01背包+贪心)

    这道题有个小小的坎,就是低于5块不能选,大于5块,可以任意选,所以就在初始条件判断一下剩余钱数,然后如果大于5的话,这时候就要用到贪心的思想,只要大于等于5,先找最大的那个,然后剩下的再去用背包去选择 ...

  4. hdu 2546 饭卡 01背包

    先将前n-1个从小到大排序.对m-5进行01背包.然后答案就是m-dp[m-5]-a[n-1] 至于为什么最后减去最贵的菜品,而不是把最贵的菜品也放到01背包里呢, 由于假设能够把最贵菜品a[n-1] ...

  5. HDU 2546 饭卡 01背包变形

    题目大意:中文题就不多说了 题目思路:由题意可知,只要高于5元,就可以随便刷,那我们就把最贵的留在最后刷.但是如果低于5元就什么也不能刷(哪怕你要买的物品价格不足五元),所以我们可以先求出(n-5)元 ...

  6. hdu 2546 饭卡(背包)

      设饭卡余额为total 此题经分析 可以得出:要求选出一些饭菜 时消费量尽量接近total-5元 然后再买一个饭菜 以达到透支... 可以证明 最后买的那个饭菜是饭菜中价值最大的. 证明 设a1 ...

  7. hdoj 2546 饭卡(0-1背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546 思路分析:该问题为0-1背包问题的变形题:问题求余额最少,设开始的余额为V,则求得用V-5可以买 ...

  8. HDOJ(HDU).2546 饭卡(DP 01背包)

    HDOJ(HDU).2546 饭卡(DP 01背包) 题意分析 首先要对钱数小于5的时候特别处理,直接输出0.若钱数大于5,所有菜按价格排序,背包容量为钱数-5,对除去价格最贵的所有菜做01背包.因为 ...

  9. HDU 2546 饭卡(01背包)

    题目代号:HDU 2546 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546 饭卡 Time Limit: 5000/1000 MS (Java/ ...

随机推荐

  1. win7右下角无线网图标显示未连接,但是实际上已连接上,也能上网

    首先,要确实是不是服务启动的问题,方法很简单,重新启动电脑就可以. 如果问题依旧,那么按下Win+R快捷键,输入“services.msc”,打开服务界面. 然后会看到右侧窗口出现好多设置项,找到“R ...

  2. Android MediaRecorder录音与播放

    上一篇讲到了使用意图录音.这篇文章将使用MediaRecorder类来录音,从而提供很多其它的灵活性. 效果图: 源码奉上: <LinearLayout xmlns:android=" ...

  3. 在linux命令行中编译和运行java文件

    同时加载编译多个jar包和java文件 在个人平常使用或者当我们把代码部署到linux服务器上的时候,我们经常需要通过命令行编译和运行java文件,网上关于这个的方法大多是通过 javac -cp f ...

  4. java notify notifyAll

    notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法. void notify(): 唤醒一个正在等待该对象的线程.void notifyAll(): 唤醒所 ...

  5. 【转载】TCP和TCP/IP的区别

    TCP/IP协议(Transmission Control Protocol/Internet Protocol)叫做传输控制/网际协议, 又叫网络通讯协议,这个协议是Internet国际互联网络的基 ...

  6. 使用 Vagrant 构建开发环境

    使用 Vagrant 构建开发环境 摘要:本文描述了如使用 Vagrant 构建统一的开发环境. 问题 作为开发人员,我们通常面临的问题有: 开发环境需要手工安装配置,这包括操作系统(CentOS.U ...

  7. Android ListView分页,动态添加数据

    1.ListView分页的实现,重点在于实现OnScrollListener接口,判断滑动到最后一项时,是否还有数据可以加载, 我们可以利用listView.addFootView(View v)方法 ...

  8. Android Studio集成Genymotion 及Genymotion 配置ADB

    1.打开 Android Studio,依次[File]-[Settings],快捷键  Ctrl + Alt + S 2.在打开的 settings 界面里找到 plugins 设置项,点击右侧的“ ...

  9. 在Orchard CMS Theme 用代码定义布局Widgets 配置

    在上篇中主要详细的叙述了代码的编写,这一篇主要讲解配置.可能有人会有疑问,在上一篇的代码里只有对数据的展示部分的编写,并没有提供数据源.这就是Orchard的强大之处,数据源是通过在后台配置的,那有人 ...

  10. haproxy tcp 反向代理

    配置如下: global log 127.0.0.1 local3 warning nbproc 1 maxconn 65535 daemon defaults log global option d ...