天天看点

买书动态规划java_买书问题——动态规划C++

买书问题

题目:

在节假日的时候,书店一般都会做促销活动。由于《哈利波特》系列相当畅销,店长决定通过促销活动来回馈读者。上柜的《哈利波特》平装书系列中,一共有五卷。假设每一卷单独销售均需8欧元。如果读者一次购买不同的两卷,就可以扣除5%的费用,三卷则更多,假设具体折扣的情况如下:

本数

折扣

2

5%

3

10%

4

20%

5

25%

在一份订单中,根据购买的卷数及本数,就会出现可以应用不同折扣规则的情况。但是,一本书只会应用一个折扣规则。比如,读者一共买了两本卷一,一本卷二。那么,可以享受5%的折扣。另外一本卷一则不能享受折扣。如果有多种折扣,希望计算出的总额尽可能的低。

要求根据以上需求,设计出算法,能够计算出读者所购买一批书的最低价格。

思路:

1. 用动态规划首先需找到递归公式,因为动态规划是由顶向下递归的,自顶向下求解,根据底层结果得到最终解。

2. 5卷数的价格相同,如果用x1...x5对应1~5卷书的本数,F(x1,x2,x3,x4,x5)表费用,那F(x1,x2,x3,x4,x5)=F(x2,x1,x3,x4,x5),根据排列组合,就有5!种表示方法,因此没有必要区分不同的卷,可以让书本按递减(或递增)来表示,(Y1,Y2,Y3,Y4,Y5)是x1,x2,x3,x4,x5的重排列,Y1>=Y2>=Y3>=Y4>=Y5。

3. 递归公式:

F(Y1,Y2,Y3,Y4,Y5)

=0                  (当Y1=Y2=Y3=Y4=Y5=0)

=min{

5*8*(1-0.25)+F(Y1-1,Y2-1,Y3-1,Y4-1,Y5-1),          (当Y5>=0)

4*8*(1-0.20)+F(Y1-1,Y2-1,Y3-1,Y4-1,Y5),              (当Y4>=0)

3*8*(1-0.10)+F(Y1-1,Y2-1,Y3-1,y4,Y5),                  (当Y3>=0)

2*8*(1-0.05)+F(Y1-1,Y2-1,Y3,Y4,Y5),                      (当Y2>=0)

8+F(y1-1,y2,y3,y4,y5),                                           (当Y1>=0)

}

实现:

#include#include#define n 5

#define INF 9999

using namespace std;

double min5(double a,double b,double c,double d,double e)//求5个double数的最小值

{

return min(min(min(a,b),min(c,d)),e);

}

double F(int y1,int y2,int y3,int y4,int y5)//递归实现动态规划

{

if(y1+y2+y3+y4+y5==0)return 0;//递归出口

//排序

int p[5]={y1,y2,y3,y4,y5};

sort(p,p+5,[](int a,int b){

return a=1)t5=5*8*(1-0.25)+F(y1-1,y2-1,y3-1,y4-1,y5-1);

if(y4>=1)t4=4*8*(1-0.20)+F(y1-1,y2-1,y3-1,y4-1,y5);

if(y3>=1)t3=3*8*(1-0.10)+F(y1-1,y2-1,y3-1,y4,y5);

if(y2>=1)t2=2*8*(1-0.05)+F(y1-1,y2-1,y3,y4,y5);

if(y1>=1)t1=8+F(y1-1,y2,y3,y4,y5);

//cout<>x[i];

}

sort(x,x+n,[](int a,int b){

return a