zoukankan      html  css  js  c++  java
  • HDU _2546 01背包问题

    A - 饭卡
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Submit Status

    Description

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

    Input

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

    n=0表示数据结束。
     

    Output

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

    Sample Input

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

    Sample Output

    -45
    32
     

     好久没做背包题目了,又有点概念不清了

    自己思维还是有点乱,一开始就在纠结这个卡上余额为负值的情况,然后按照常规背包的做法,先把东西塞进去,遇到减出来时负值的情况,则减去最大价值的菜

    看上去好像可以,但是会WA

    真正的准确思路其实不难想到,在卡上余额大于5的时候,就按常规背包去塞最大化的东西,也就是说,之前就刻意缩小背包容量,使得它为 w-5;这样就能求出卡余额在5元以上的时候,最大的消费额。。。当然,在这之前还要找到最大值得菜,这样,背包之后,再减去最大值的菜。就一定是最余额了。。

    其实思路真的很简单,以大于5的卡,做背包,。。剩下的只要减去最大值得菜就行。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int fruit[1005];
    int card[1005];
    int max(int x,int y)
    {
        if (x>y) return x;
        else
            return y;
    }
    int main()
    {
        int n;
        while (scanf("%d",&n)&&n)
        {
            int i;
            for (i=0; i<n; i++)
                scanf("%d",&fruit[i]);
            int maxn=0;
            int loc;
            for (i=0; i<n; i++)
                if (maxn<fruit[i])
                {
                    maxn=fruit[i];
                    loc=i;
                }
            int yu;
            scanf("%d",&yu);
            if (yu<5)      //如果初始额度即为小于5,则直接输出
            {
                printf("%d
    ",yu);
                continue;
            }
            memset(card,0,sizeof card);
            for (int j=0; j<n; j++)
            {
                if (j==loc) continue;
                for (int k=yu-5; k>=0; k--) //一度忘记了,要从最大值开始递减背包,一开始居然从0开始递增背包,这样会出现状态混乱,这样才能保证每次比较的是前一次的状态和当前状态。
                {
                    if (k>=fruit[j])
                        card[k]=max(card[k],card[k-fruit[j]]+fruit[j]);
                }
            }
            int ans=yu-card[yu-5]-maxn;
            printf("%d
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    android PopupWindow的使用
    工作
    android StringUtils
    Android DrawableTextView图片文字居中显示
    android 布局使用GridView
    android 微信支付流程
    日记 2016.10.23 好好努力 不要放弃治疗!
    一、Python爬虫
    【Python工具】Excle 读写 (使用 xlrd 和 xlrt)
    Django中,图片显示问题--Django中静态文件处理方法指南
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3229415.html
Copyright © 2011-2022 走看看