上节提到了一个关于买书的练习,原文只是简单描述了下思路,然后我用java代码实现并做了少量优化。由于并未找到相关的运行实例,所以如有任何错误感谢指出。
原文如下:
题目一:买书
有一书店引进了一套书,共有3卷,每卷书定价是60元,书店为了搞促销,推出一个活动,活动如下:
如果单独购买其中一卷,那么可以打9.5折。
如果同时购买两卷不同的,那么可以打9折。
如果同时购买三卷不同的,那么可以打8.5折。
如果小明希望购买第1卷x本,第2卷y本,第3卷z本,那么至少需要多少钱呢?(x、y、z为三个已知整数)。
当然,这道题完全可以不用动态规划来解,但是现在我们是要学习动态规划,因此请想想如何用动态规划来做?
代码如下:
import java.util.Scanner;
public class dp_algo {
static double[][][] moneys=null;
public static void main(String[] args) {
System.out.println("input:");
Scanner sc=new Scanner(System.in);
int x=sc.nextInt();
int y=sc.nextInt();
int z=sc.nextInt();
moneys=new double[x+1][y+1][z+1];
System.out.println(GetMinMoney(x,y,z));
}
private static double min(double ...args){
double mNum=args[0];
for(int i=1;i<args.length;i++){
if(mNum>args[i]){
mNum=args[i];
}
}
return mNum;
}
private static double GetMinMoney(int x, int y, int z) {
double m=0;
double s1=0,s2=0,s3=0;
if(moneys[x][y][z]>0)
return moneys[x][y][z];
//试验中数据的对称性,及xyz=(001)或(100)效果一样,所以这里我们规定x>=y>=z
if(x==0){//此时y=z=0
m=0;
}else if(z>0){//此时x>=1,y>=1,z>=1
s1=60*0.95+GetMinMoney(x,y,z-1);//取一本
s2=120*0.9+GetMinMoney(x,y-1,z-1);//取两本
s3=180*0.85+GetMinMoney(x-1,y-1,z-1);//取三本,下同
m=min(s1,s2,s3);
}else if(y>0){//此时x>=1,y>=1,z==0
s1=60*0.95+GetMinMoney(x,y-1,z);
s2=120*0.9+GetMinMoney(x-1,y-1,z);
m=min(s1,s2);
}else if(x>0){//此时x>=1,y=z=0
//m=60*0.95+GetMinMoney(x-1,y,z);
return m=60*0.95*x;
}
moneys[x][y][z]=m;
return m;
}
}
输入与输出:
input:
4 3 2//输入
471.0//输出