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;
    }
    
  • 相关阅读:
    Java学习8.31
    Java学习8.30
    Java学习8.29
    Java学习8.28
    Java学习8.27
    Java学习8.26
    242. Valid Anagram 有效的字符串
    680. Valid Palindrome II 对称字符串-可删一个字母版本
    151. Reverse Words in a String翻转一句话中的单词
    155. Min Stack 155.最小栈
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5521413.html
Copyright © 2011-2022 走看看