• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
HDU 2546 饭卡 (01背包问题)

题意:中文的吧,飘过~

析:学过DP的都应该感觉到是动态规划吧,就是一个01背包问题,不同的是,这个题又加入一些新的条件,就是不满5元不能消费,过了5元即使超了也行(这个学校真不错,都可以预支),最后让你求剩下最少的金额(可以是负的),根据贪心我们应该知道最后一个买最贵的,为什么呢,如果在前面就先取了最贵的,那么剩余金额到快接近或者等于为5元时,然后再买一个肯定比不上,最后快接近或者等于5元时,再买那个最贵的剩下的少,当然还有一种情况就是买完所有的东西后,仍然大于或者等于5元,那么最后买最贵的和不是最后买结果是一样的,综上,我们应该最后买那个最贵的。

所以我们就先取出来5元,相当于是在m-5的背包中装物品,使其最大,后面就很easy了。

代码如下:

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <queue>
#include <iomanip>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <map>
#include <list>

using namespace std;
typedef long long LL;
const int maxn = 1000 + 10;
int a[maxn], d[maxn];

int main(){
    int n, m;
    while(scanf("%d", &n), n){
        int maxnn = -1, indx;
        for(int i = 1; i <= n; ++i){
            scanf("%d", &a[i]);
            if(maxnn < a[i]){ maxnn = a[i];  indx = i; } //找一下最大的价格,最后再减掉
        }
        scanf("%d", &m);

        if(m < 5){  printf("%d\n", m);  continue; } //小于5,都不花费,直接输出结果
        memset(d, 0, sizeof(d));
        for(int i = 1; i <= n; ++i){
            if(i == indx)  continue;
            for(int j = m-5; j >= a[i]; --j) //保证最后价格大于等于5
                d[j] = max(d[j], d[j-a[i]] + a[i]); //01背包
        }

        printf("%d\n", m-d[m-5]-a[indx]);
    }
    return 0;
}

 

posted on 2016-05-23 21:07  dwtfukgv  阅读(198)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3