• 动态规划——买书问题


    转载自CSDN 朱超迪,链接:http://blog.csdn.net/q623702748/article/details/51592427

    在朱超迪的原代码上做了一些修改

    问题描述:
             在节假日的时候,书店一般都会做促销活动。由于《哈利波特》系列相当畅销,店长决定通过促销活动来回馈读者。上柜的《哈利波特》平装本系列中,一共有五卷。假设每一卷单独销售均需8欧元。如果读者一次购买不同的两卷,就可以扣除5%的费用,三卷则更多。假设具体折扣的情况如下:
     
    本数     折扣
    2            5%
    3           10%
    4           20%
    5           25%
            
           在一份订单中,根据购买的卷数及本数,就会出现可以应用不同折扣规则的情况。但是,一本书只会应用一个折扣规则。比如,读者一共买了两本卷一,一本卷二。那么,可以享受到5%的折扣。另外一本卷一则不能享受折扣。如果有多种折扣,希望计算出的总额尽可能的低。
             要求根据以上需求,设计出算法,能够计算出读者所购买的一批书的最低价格。
                                                                                      
                                                                                          
    思路分析:
             看到这个题目,任何人一开始想到的都是希望让书本尽可能享受高折扣。但是随着书本数目大于5本的时候,享受的总折扣就会相应出现了变化。            
             举个例子, 当输入的数据为(2,2,2,1,1)的时候,如果按照享受最高折扣计算,那么对应的折扣策略就会拆分变成(1,1,1,1,1)和(1,1,1,0,0)两种,总价格变为8×0.75×5+8×0.9×3= 51.6欧元。但是如果我们变一下策略,选择4+4,购买序列变为(1,1,1,1,0)以及(1,1,1,0,1),那么总共花费8×0.8×5+8×0.8×5=51.2欧元。
    看到这里,我们已经可以使用动态规划通过计算总折扣数来计算最优惠价格,当然,也可以采用优化的贪心算法来实现,因为贪心算法求解这类题目都是近似解,与最优解相近。
     
    解题:
    先将现有条件转换一下(用百分比表示书本单价的多少倍):
     
    本数
    相对于书本单价的百分比
    1
    100%
    2
    190%
    3
    270%
    4
    320%
    5
    375%
     
    具体说明一下吧:
    当只有一本书的时候,没有折扣,所以为100%,即原价8欧元购买;
    当有两本不同的书本,享有5%折扣,原本总价为200% ,减掉每本5%折扣,为190%,即15.2欧元;
    当有三本不同的书本,享有10%折扣,原本总价为300%,减掉每本10%折扣,为270%,即21.6欧元;
    当有四本不同的书本,享有20%折扣,原本总价为400%,减掉每本的20%折扣,为320%,即25.6欧元;
    当有五本不同的书本,享有25%折扣,原本总价为500%,减掉每本的25%折扣,为375%,即30欧元;
    以上折扣数据存放在minDis[6]中
    即minDIs[6] = {0 , 1,1.9 , 2.7 , 3.2 , 3.75 };
    根据上述条件描述,我们可以定义出一条状态转移方程(核心):
    F[Y1,Y2,Y3,Y4,Y5] = min{   //定量 + 变量  的组合
    8*minDis[5]+F(Y1-1,Y2-1,Y3-1,Y4-1,Y5-1),
    8*minDis[4]+F(Y1-1,Y2-1,Y3-1,Y4-1,Y5),
    8*minDis[3]+F(Y1-1,Y2-1,Y3-1,Y4,Y5),
    8*minDis[2]+F(Y1-1,Y2-1,Y3,Y4,Y5),
    8*minDis[1]+F(Y1-1,Y2,Y3,Y4,Y5)
    }
           其中必须保证Y1>=Y2>=Y3>=Y4>=Y5,这样才不会出现更多的冗余数据。例如:(2,2,2,1,1)和(1,2,1,2,2)虽然不同,但是结果都是一样的。

    下面是这个问题的代码(我个人修改过了):

     1  //买书问题
     2 
     3     float discount[6] = {0,1,1.9,2.7,3.2,3.75};
     4     float price[6][6][6][6][6] = {0};
     5     int num[6] = { 0 };
     6     for (int i = 1; i <= 5; ++i)
     7         cin >> num[i];
     8     int temp = 0;
     9     bubble_sort(num, 5);
    10     
    11     int num1[6] = { 0 };
    12     float arr[6] = { 0 };
    13     float min = 0;
    14     for (int a5 = 0; a5 <= num[5];++a5)
    15     for (int a4 = a5; a4 <= num[4];++a4)
    16     for (int a3 = a4; a3 <= num[3]; ++a3)
    17     for (int a2 = a3; a2 <= num[2]; ++a2)
    18     for (int a1 = a2; a1 <= num[1]; ++a1){
    19         if (a5 > 0){
    20             num1[5] = a5 - 1;
    21             num1[4] = a4 - 1;
    22             num1[3] = a3 - 1;
    23             num1[2] = a2 - 1;
    24             num1[1] = a1 - 1;
    25             bubble_sort(num1, 5);
    26             arr[5] = 8 * discount[5] + price[num1[1]][num1[2]][num1[3]][num1[4]][num1[5]];
    27         }
    28         if (a4 > 0){
    29             num1[5] = a5;
    30             num1[4] = a4 - 1;
    31             num1[3] = a3 - 1;
    32             num1[2] = a2 - 1;
    33             num1[1] = a1 - 1;
    34             bubble_sort(num1, 5);
    35             arr[4] = 8 * discount[4] + price[num1[1]][num1[2]][num1[3]][num1[4]][num1[5]];
    36         }
    37         if (a3 > 0){
    38             num1[5] = a5;
    39             num1[4] = a4;
    40             num1[3] = a3 - 1;
    41             num1[2] = a2 - 1;
    42             num1[1] = a1 - 1;
    43             bubble_sort(num1, 5);
    44             arr[3] = 8 * discount[3] + price[num1[1]][num1[2]][num1[3]][num1[4]][num1[5]];
    45         }
    46         if (a2 > 0){
    47             num1[5] = a5;
    48             num1[4] = a4;
    49             num1[3] = a3;
    50             num1[2] = a2 - 1;
    51             num1[1] = a1 - 1;
    52             bubble_sort(num1, 5);
    53             arr[2] = 8 * discount[2] + price[num1[1]][num1[2]][num1[3]][num1[4]][num1[5]];
    54         }
    55         if (a1 > 0){
    56             num1[5] = a5;
    57             num1[4] = a4;
    58             num1[3] = a3;
    59             num1[2] = a2;
    60             num1[1] = a1 - 1;
    61             bubble_sort(num1, 5);
    62             arr[1] = 8 * discount[1] + price[num1[1]][num1[2]][num1[3]][num1[4]][num1[5]];
    63         }
    64         min = arr[1];
    65         for (int k = 1; k <= 5;++k)              
    66             if ((arr[k] < min&&arr[k]>0)||min==0)min = arr[k];
    67         price[a1][a2][a3][a4][a5] = min;
    68     }
    69     cout << price[num[1]][num[2]][num[3]][num[4]][num[5]] << endl;
    70     return 0;
    71 }

    其中bubble_sort是一个基本的冒泡排序算法,由于问题规模有限,我就写了个最简单的冒泡排序,由于比较简单所以这里不再提供。

  • 相关阅读:
    Docker GitLab镜像部署
    Kubernetes集群部署之三ETCD集群部署
    Kubernetes集群部署之二CA证书制作
    Kubernetes集群部署之一系统环境初始化
    docker开源仓库Harbor部署笔记
    git分支
    git高清技能图
    vue+uwsgi+nginx部署路飞学城
    git基础
    git安装与初始化
  • 原文地址:https://www.cnblogs.com/messi2017/p/8092619.html
Copyright © 2020-2023  润新知