一、 实验目的
对于给定欲购商品的价格和数量,以及优惠商品价,编程计算所购商品应付的最少费用。
二、 实验要求
数据输入:
由文件input.txt提供预购商品数据。控制台的第 1 行中有 1 个整数 B(0≤B≤5),表示所购商品种类数。接下来的 B 行,每行有 3 个数 C,K 和 P。C 表示商品的编码(每种商品有 唯一编码),1≤C≤999。K 表示购买该种商品总数,1≤K≤5。P 是该种商品的正常单价(每件商品的价格),1≤P≤999。请注意,一次最多可购买 5*5=25 件商品。
由文件offe.txt提供优惠商品价数据。接下来输入 1 个整数 S(0≤S≤99),表示 共有 S 种优惠商品组合。接下来的 S 行,每行的第一个数描述优惠商品组合中商品的种类数 j。接着是 j 个数字对(C,K),其中 C 是商品编码,1≤C≤999。K 表示该种商品在此组合中的数量,1≤K≤5。每行最后一个数字 P(1≤ P≤9999)表示此商品组合的优惠价。
数据输出: 将计算出的所购商品应付的最少费用输出到文件output.txt
三、 实验原理
找出问题的规律,设cost(a,b,c,d,e)表示购买商品组合(a,b,c,d,e)需要的最少费用,A[k],B[k],C[k],D[k],E[k]表示第k种优惠方案的商品组合。offer(m)是第m种优惠方案的价格。如果cost(a,b,c,d,e)使用了第m种优惠方案,则找出最优子问题的递归表达式:cost(a,b,c,d,e)=cost(a-A[m],b-B[m],c-C[m],d-D[m],e-E[m])+offer(m) 。即该问题具有最有子结构性质,可以用动态规划算法来实现。
四、实验结果
六、附录
#include <iostream>
#include <bits/stdc++.h>
#define MAXCODE 999//商品编码的最大值
#define SALECOMB 99//优惠商品组合数
#define KIND 5 //商品种类
#define QUANTITY 5//购买某种商品数量的最大值
using namespace std;
struct Commodity
{
int piece;
int price;
};
int b;//购买商品种类数
int s;//当前优惠组合数
int num[MAXCODE+1];//记录商品编码与商品种类的对应关系
int product[KIND+1];//记录不同种类商品的购买数量
int offer[SALECOMB+1][KIND+1];//offer[i][j]: 商品组合的优惠价(j=0);某种优惠组合中某种商品需要购买的数量(j>0)
Commodity purch[KIND+1];//记录不同商品的购买数量和购买价格
int cost[QUANTITY+1][QUANTITY+1][QUANTITY+1][QUANTITY+1][QUANTITY+1];//记录本次购买的总花费
void init();
void minicost();
void comp(int i);
void out();
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
init();
comp(1);
out();
return 0;
}
void init()
{
int i,j,n,p,t,code;
for(i=0;i<100;i++)
for(j=0;j<6;j++)
offer[i][j]=0;
for(i=0;i<6;i++)
{
purch[i].piece=0;
purch[i].price=0;
product[i]=0;
}
freopen("input.txt","r",stdin);
cin>>b;
for(i=1;i<=b;i++)
{
cin>>code;
cin>>purch[i].piece>>purch[i].price;
num[code]=i;
}
fclose(stdin);
cin.clear();
freopen("offer.txt","r",stdin);
cin>>s;
for(i=1;i<=s;i++)
{
cin>>t;
for(j=1;j<=t;j++)
{
cin>>n>>p;//p代表该类商品优惠数量
offer[i][num[n]]=p;
}
cin>>offer[i][0];
}
fclose(stdin);
}
void minicost()
{
int i,j,k,m,n;//已经购买1~5种商品的数量
int p;
int minm=0;//最小花销
for(i=1;i<=b;i++)
minm+=product[i]*purch[i].price;//正常价格购买
for(p=1;p<=s;p++)//购买数量减去优惠规定数量
{
i=product[1]-offer[p][1];
j=product[2]-offer[p][2];
k=product[3]-offer[p][3];
m=product[4]-offer[p][4];
n=product[5]-offer[p][5];
if(i>=0&&j>=0&&k>=0&&m>=0&&n>=0&&cost[i][j][k][m][n]+offer[p][0]<minm)
minm=cost[i][j][k][m][n]+offer[p][0];
}
cost[product[1]][product[2]][product[3]][product[4]][product[5]]=minm;
}
void comp(int i)
{
if(i>b)
{
minicost();
return;
}
for(int j=0;j<=purch[i].piece;j++)
{
product[i]=j;
comp(i+1);
}
}
void out()
{
freopen("output.txt","w",stdout);
cout<<cost[product[1]][product[2]][product[3]][product[4]][product[5]];
}