zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", m-d[m-5]-a[indx]);
        }
        return 0;
    }
    
  • 相关阅读:
    Qt之界面数据存储与获取(使用setUserData()和userData())
    UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别
    Entity Framework Model First下改变数据库脚本的生成方式
    keepalive学习
    函数、极限、连续
    C#集合基础与运用
    面向查询服务的参数化查询
    WinDbg 命令手册
    知识管理方法论
    项目管理Project
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5521413.html
Copyright © 2011-2022 走看看