zoukankan      html  css  js  c++  java
  • 牛客网——代金券组合

    题目:链接:https://www.nowcoder.com/questionTerminal/5d2405da8d364eafbaca1de9bc2a0d4e?answerType=1&f=discussion
    来源:牛客网


    [编程题]代金券组合
    • 热度指数:766 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M

    近期某商场由于周年庆,开启了“0元购”活动。活动中,消费者可以通过组合手中的代金券,实现0元购买指定商品。

    聪明的小团想要用算法来帮助他快速计算:对于指定价格的商品,使用代金券凑出其价格即可,但所使用的代金券总面额不可超过商品价格。由于代金券数量有限,使用较少的代金券张数则可以实现价值最大化,即最佳优惠。

    假设现有100元的商品,而代金券有50元、30元、20元、5元四种,则最佳优惠是两张50元面额的代金券;而如果现有65元的商品,则最佳优惠是两张30元代金券以及一张5元代金券。

    请你帮助小团使用一段代码来实现代金券计算。




    输入描述:
    多组输入输出,读到s=0时结束
    输入可以有多个测试样例,每个测试由两行组成。

    其中第一行包含一个整数P,表示商品的价格,1≤P≤10000;输入P为0时表示结束。

    第二行包含若干整数,使用空格分割。其中第一个整数N(1≤N≤20)表示有多少种代金券,其后跟随M个整数,表示手中持有的代金券面额(1≤N≤1000),每种代金券数量不限。


    输出描述:

    找到最少张数的代金券,使其面额恰好等于商品价格。输出所使用的代金券数量;

    如果有多个最优解,只输出其中一种即可;

    如果无解,则需输出“Impossible”。

    示例1

    输入

    65
    4 50 30 20 5
    0

    输出

    3以上,就是全部题目,相信学过DP的朋友们,都能看出来是个DP的动态规划题目,引入一个数组F[n]来记录0——cash元的最优解有几张(n 就是遍历 0 - cash 的,因为你最终的答案是建立在cash之前的金额上的),想要遍历出最优解首先得把F[n] 初始一个很大的值,在遍历中用min()函数,如果遇到最优解的方法将最优解的小值替换掉较大的解。
    如果所有0-cash所有的钱都遍历完了,但f[cash] 还等于你初始设置的呢个数,则代表没有代金券能刚好抵消商品价格,就是没有最优的解,所以输出Impossible,反之,输出f[cash]最优解。
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main(){
        int cash,s;
        int coins[21];
        while(~scanf("%d",&cash)&& cash != 0)
        {
            scanf("%d",&s);
            for(int i = 0 ; i < s ; i ++)
            {
                scanf("%d",&coins[i]);
            }
            
            sort(coins,coins+s);
            
               int F[10000];
               for(int i = 0 ; i <= cash ; i ++){
                   F[i] = cash +1;                // 这一块就是为了初始值,设一个很大的数字就行
            }
            
            F[0] = 0;         // 在0 元时,最优解就是0张;
         for(int j = 0 ; j <= cash ; j ++)   //枚举金钱数 
    { for(int k = 0 ; k < s ; k ++) { if(j < coins[k]) // 因为代金券不能大于金钱额度,所以遍历到直接跳出了,毕竟经过排序,后面的代金券的值都大于目前代金券的值。 break; else F[j] = min(F[j-coins[k]]+1 ,F[j]); //反之,如果小于,则将金钱额度-目前这个代金券 得到的是上一个没用这次代金券的值, 将使用本次代金券的值 和 不使用代金券的值 相对比,取最优解。+1的原因是F数组里存的最优解是几张,如果使用这次代金券则张数必加1 } } if(F[cash] == cash+1) cout << "Impossible" << endl; else cout << F[cash] << endl; } }
  • 相关阅读:
    MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】
    一致性哈希算法原理
    【MySQL (六) | 详细分析MySQL事务日志redo log】
    Replication基础(六) 复制中的三个线程(IO/SQL/Dump)
    硬盘基本知识(磁头、磁道、扇区、柱面
    MySQL架构总览->查询执行流程->SQL解析顺序
    Redis之AOF重写及其实现原理
    MySQL binlog中的事件类型
    linux(mac) 编译安装MySQL
    写给自己看的Linux运维基础(四)
  • 原文地址:https://www.cnblogs.com/wtzmz/p/12920099.html
Copyright © 2011-2022 走看看