• 饭卡问题(0-1背包的变形)


    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于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

    题目大意 :给你一些钱,让你去食堂消费,每个菜只能点一次,且5元以上可以任意点,5元以下不可以点,让你求最后剩下的最少钱。

    题目分析 :我们只要把5元单独出来,用这5元消费最大的那个值。剩下的0-1背包就可以了。

    题目收获 :动态转移方程的变形

    AC代码 :
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #define maxn 1005
    using namespace std;
    int d[maxn];
    bool cmp(int x, int y)
    {
        return x > y;
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        int n,m;
        while (scanf("%d",&n)!=EOF && n)
        {
            int ni[maxn];//储存价格的数组
            memset(d, 0, sizeof(d));//清空上一次计算的值
            for (int i = 1; i <= n; i++)
                scanf("%d",&ni[i]);
            scanf("%d", &m);
            if (m < 5)//小于5元最直接输出
            {
                printf("%d
    ", m);
                continue;
            }
            sort(ni + 1, ni + 1 + n,cmp);//求最大值
            int ans = ni[1];//储存最大值
            ni[1] = 0;//最大者变为0
            for (int i = 1; i <= n; i++)//0-1模板
            {
                for (int j = m-5; j >= 1; j--)
                {
                    if (j >= ni[i])
                        d[j] = max(d[j], d[j - ni[i]] + ni[i]);//转移方程有点点变化
                }
            }
            printf("%d
    ", (m - 5) - d[m - 5] + 5 - ans);
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 3668: [Noi2014]起床困难综合症【贪心】
    浅谈错排公式的推导及应用
    Python爬虫笔记(一):爬虫基本入门
    机器理解大数据秘密:聚类算法深度剖析
    想了解概率图模型?你要先理解图论的基本定义与形式
    MATLAB命令大全+注释小结
    【批处理学习笔记】第二十九课:ASCII码
    【批处理学习笔记】第二十八课:声音和控制
    【批处理学习笔记】第二十七课:视窗
    【批处理学习笔记】第二十六课:返回值
  • 原文地址:https://www.cnblogs.com/7750-13/p/7363949.html
Copyright © 2020-2023  润新知