商店中每种商品都有标价。例如,一朵花的价格是2元。一个花瓶的价格是5 元。为了吸引顾客,商店提供了一组优惠商品价。
优惠商品是把一种或多种商品分成一组,并降价销售。例如,3朵花的价格不是6元而是5元。2 个花瓶加1 朵花的优惠价是10 元。
试设计一个算法,计算出某一顾客所购商品应付的最少费用。
编程任务:对于给定欲购商品的价格和数量,以及优惠商品价,编程计算所购商品应付的最少费用。
数据输入:由文件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件商品。
由文件offer.txt提供优惠商品价数据。
文件的第1行中有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中。
输入文件示例
input.txt
2
7 3 2
8 2 5
offer.txt
2
1 7 3 5
2 7 1 8 2 10
输出文件示例
output.txt
14
这道题是一道动态规划的题,题目限制最多提供五种商品,可以建一个五维数组来表示最小花费
最小花费就是
min( 单买各种商品 , 使用套餐买各种商品); =
min( (商品i单价P*数量k)的和 , (商品需求数量k – 套餐里该商品的数量J.k)的价格 + 套餐的价格 )
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
struct youhui{
int price; ///J[i].price 代表 优惠组合i 的价格
int k[100]; ///J[i].k[j] 代表 在优惠组合i里编号为j的商品的数量
}J[100]; ///J[i] : 第i种优惠的组合
int cost[6][6][6][6][6]; ///cost[i][j][k][l][m] 代表 当要求购买第一种商品数量为i,第二种为j.....时最小花费
int P[1000]; ///P[i] 代表 编号为i的商品的单价
int num[1000]; ///num[i] 代表 给出的商品的编号
int K[1000];/// K[i] 代表编号为i的商品所要求的数量
int B,S; ///B代表给出B种商品,S代表 有S种优惠组合
void nn(string s){
cout<<s<<endl;
}
void init(){
for(int i = 0; i < 6; ++i)
for(int j = 0; j < 6; ++j)
for(int k2 = 0; k2 < 6; ++k2)
for(int l = 0 ; l < 6; ++l)
for(int m = 0; m < 6; ++m)
cost[i][j][k2][l][m] = 0;
for(int i = 0; i < 100; ++i){
memset(J[i].k,0,sizeof(int));
}
}
void print2(){
for(int i = 1; i <= B; ++i) printf("%d: %d---%d \n",num[i],K[num[i]],P[num[i]]);
nn("-----------------------");
for(int i = 1; i <= S ;++i){
printf("price: %d\n",J[i].price);
for(int j = 0; j < 100; ++j){
if(J[i].k[j] != 0) printf("%d : %d\n",j,J[i].k[j]);
}
printf("\n");
}
}
int main()
{
int tmp_c;
///*************初始化***********/////
memset(P,0,sizeof(int));
memset(K,0,sizeof(int));
memset(num,0,sizeof(int));
init();
///************输入数据***************////
FILE *fp;
fp = fopen("1.txt","r");
if(fp == NULL) printf("wuwu\n");
fscanf(fp,"%d",&B);
for(int i = 1; i <= B;++i){
int tmp;
fscanf(fp,"%d",&num[i]);
tmp = num[i];
fscanf(fp,"%d%d",&K[tmp],&P[tmp]);
}
fscanf(fp,"%d",&S);
for(int i = 1; i <= S; ++i){
int count;
fscanf(fp,"%d",&count);
for(int j = 1; j <= count; ++j){
fscanf(fp,"%d",&tmp_c);
fscanf(fp,"%d",&J[i].k[tmp_c]);
}
fscanf(fp,"%d",&J[i].price);
}
///********主要运算部分*****************************///
cost[0][0][0][0][0] = 0;
for(int i = 0; i <= K[ num[1] ]; ++i){
for(int j = 0; j <= K[ num[2] ]; ++j){
for(int k1 = 0; k1 <= K[ num[3] ]; ++k1){
for(int l = 0; l <= K[ num[4] ]; ++l){
for(int m = 0; m <= K[ num[5] ]; ++m){
int mmin = i*P[num[1]] +
j*P[num[2]] +
k1*P[num[3]]+
l*P[num[4]] +
m*P[num[5]]; ///单卖的花费
for(int n = 1; n <= S;n++){ ///各种套餐的花费
if(i < J[n].k[num[1]] ||
j < J[n].k[num[2]] ||
k1 < J[n].k[num[3]] ||
l < J[n].k[num[4]] ||
m < J[n].k[num[5]] ) continue;
int t = cost[i-J[n].k[num[1]]][j-J[n].k[num[2]]][k1-J[n].k[num[3]]][l-J[n].k[num[4]]][m-J[n].k[num[5]]] + J[n].price;
if(t < mmin) mmin = t;
}
cost[i][j][k1][l][m] = mmin;
}
}
}
}
}
printf("%d\n",cost[K[num[1]]][K[num[2]]][K[num[3]]][K[num[4]]][K[num[5]]]);
fclose(fp);
system("pause\n");
return 0;
}
/**
2
7 3 2
8 2 5
2
1 7 3 5
2 7 1 8 2 10
**/
/***
min( 单买各种商品 , 使用套餐买各种商品);
min( 和(商品i单价P*数量k) , (需求商品数量k - 套餐里该商品的数量J.k)的价格 + 套餐的价格 )
**/