最少购物费用问题

商店中每种商品都有标价。例如,一朵花的价格是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)的价格 + 套餐的价格 )



**/



点赞