买书问题——动态规划C++
2018-03-25 21:12
197 查看
买书问题
题目:
在节假日的时候,书店一般都会做促销活动。由于《哈利波特》系列相当畅销,店长决定通过促销活动来回馈读者。上柜的《哈利波特》平装书系列中,一共有五卷。假设每一卷单独销售均需8欧元。如果读者一次购买不同的两卷,就可以扣除5%的费用,三卷则更多,假设具体折扣的情况如下:本数 | 折扣 |
2 | 5% |
3 | 10% |
4 | 20% |
5 | 25% |
要求根据以上需求,设计出算法,能够计算出读者所购买一批书的最低价格。
思路:
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<iostream> #include<algorithm> #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<b?a:b; }); y1=p[0],y2=p[1],y3=p[2],y4=p[3],y5=p[4]; double t1=INF,t2=INF,t3=INF,t4=INF,t5=INF; if(y5>=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<<"t:\n"; // cout<<t1<<" "<<t2<<" "<<t3<<" "<<t4<<" "<<t5<<endl; return min5(t1,t2,t3,t4,t5); } int main() { int x ; for(int i=0;i<n;++i) { cin>>x[i]; } sort(x,x+n,[](int a,int b){ return a<b?a:b; }); cout<<F(x[0],x[1],x[2],x[3],x[4]); return 0; }
相关文章推荐
- 0/1背包问题 - 动态规划(C++实现)
- 算法导论-第15章-动态规划:钢条切割问题自底向下方法C++实现
- c++动态规划解决硬币换零钱的问题
- 动态规划的简要总结和四个经典问题的c++实现
- c++动态规划——背包问题
- 最长公共子序列问题(c++)-动态规划
- c++实现0-1背包问题完整源码(动态规划实现)
- 一些可以用动态规划(DP)算法解决的问题(C++)
- 0-1背包问题与完全背包问题C++实现 动态规划
- 0-1背包问题与完全背包问题C++实现 动态规划
- c++实现0-1背包问题完整源码(动态规划实现)
- 算法学习 - 动态规划(DP问题)装配线问题(C++)
- 0-1背包问题与完全背包问题C++实现 动态规划
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- ACM最长公共子序列问题(动态规划)C++实现
- 背包问题,动态规划求解,matlab代码,c++代码
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- ACM最长公共子序列问题(动态规划)C++实现
- 算法学习 - 01背包问题(动态规划C++)
- 【C++】动态规划:最长递增子序列和建桥问题