• hdu 2546 饭卡 01背包


    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2546

    饭卡

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 14019    Accepted Submission(s): 4883


    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元一定可以购买成功,所以先利用贪心的思想可以想到,当花到稍微超出5元之后,去买最贵的菜。
    所以在卡的余额大于5元的时候,先把卡的余额减掉五元,并且找出最贵的菜,去掉。然后用01背包。求出这个情况下的dp[n-1][m-5].
    最后m - dp[n-1][m-5] - 最贵菜的价格就是解了。
    要注意一下少于五元的情况,是直接输出余额。
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <string>
     5 #include <algorithm>
     6 using namespace std;
     7 int n, m;
     8 int p[1010];
     9 int dp[1010][1010];
    10 int main(){
    11     while(scanf("%d", &n) && n){
    12         for(int i = 1; i <= n; i++) scanf("%d", &p[i]);
    13         sort(p+1,p+1+n);
    14         //要使剩余体积最小。 
    15         memset(dp, 0, sizeof(dp));
    16         scanf("%d", &m);
    17         if(m >= 5){
    18             for(int i = 1; i <= n-1; i++){
    19                 for(int j = 0; j <= m-5; j++){
    20                     dp[i][j] = dp[i-1][j];
    21                     if(j >= p[i]){
    22                         dp[i][j] = max(dp[i][j], dp[i-1][j-p[i]] + p[i]);
    23                     }
    24                 }
    25             } 
    26             cout<<m-dp[n-1][m-5]-p[n]<<endl;
    27         }
    28         else cout<<m<<endl;
    29     }
    30     
    31     return 0;
    32 }
  • 相关阅读:
    一些技术摘选及随想
    新技术学习方法如何学习一门新编程语言(Lua)?
    什么时候该用ASSERT?
    MFC是否过时?如何学习MFC?
    Windows桌面开发者的必备软件
    Comet技术选择,论Is node.js best for Comet?
    关于C/C++内存管理一些乱讲
    debug
    C语言趣味题目
    CSS之简单的双引号
  • 原文地址:https://www.cnblogs.com/titicia/p/4356432.html
Copyright © 2020-2023  润新知