题意“:有 b种商品 (0 <= b <= 5).,先依次给出 c(1 <= c <= 999,商品编码), k(1 <= k <= 5,需购买的数量), p (1 <= p <= 999,独立价格)。然后给出s(0 <= s <= 99)种优惠方案,给出的形式如下:每种方案包含n(1 <= n <= 5)种商品,每种商品包含c(编码),k(需购买数量)两个属性,最后是买这个方案中的所有商品给定的数量需要的总价格。问怎样选择优惠方案能最省钱?
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define nMAX 6
/** 五维数组dp表示五种(或小于五种)商品各为相应的数目时总共的价格是多少 */
int dp[nMAX][nMAX][nMAX][nMAX][nMAX];
/** code[i] = j 表示商品编码为i的商品在数组中的下标为j */
int code[1000];
/** 相应的商品数目 */
int num[nMAX];
/** 相应的商品价格 */
int price[nMAX];
int main()
{
int i, j, b;
scanf("%d", &b);
int c;
for( i = 0; i < b; i ++ ){
scanf("%d%d%d", &c, &num[i], &price[i]);
code[c] = i;
}
/** 循环变量数组*/
int index[5] = {0};
/** 按照每种商品未优惠的价格对组合购买价格进行初始化 */
for( index[0] = 0; index[0] <= num[0]; index[0] ++ )
for( index[1] = 0; index[1] <= num[1]; index[1] ++ )
for( index[2] = 0; index[2] <= num[2]; index[2] ++ )
for( index[3] = 0; index[3] <= num[3]; index[3] ++ )
for( index[4] = 0; index[4] <= num[4]; index[4] ++ ){
dp[index[0]][index[1]][index[2]][index[3]][index[4]] = price[0] * index[0] +
price[1] * index[1] + price[2] * index[2] + price[3] * index[3] + price[4] * index[4];
}
int s;
scanf("%d", &s);
/** 优惠方案中包含的商品的编码和相应所需买的数量 */
int special_code[nMAX];
int special_num[nMAX];
/** 循环每种优惠方案 */
for( i = 0; i < s; i ++ ){
/** 第i 种优惠方案所包含的商品种类数 ( < 5) */
int n;
scanf("%d", &n);
for( j = 0; j < n; j ++ ){
/** 每个种类商品的编码和数目 */
scanf("%d%d", &special_code[j], &special_num[j] );
}
/** 购买优惠方案所有包含的商品的总价格 */
int p;
scanf("%d", &p);
/*
注意:即使商品种类数 < 5 该五重循环仍适用
*/
for( index[0] = 0; index[0] <= num[0]; index[0] ++ )
for( index[1] = 0; index[1] <= num[1]; index[1] ++ )
for( index[2] = 0; index[2] <= num[2]; index[2] ++ )
for( index[3] = 0; index[3] <= num[3]; index[3] ++ )
for( index[4] = 0; index[4] <= num[4]; index[4] ++ ){
/* standard_num[i] = j 表示在去掉该优惠方案所需i 商品的数量后
* i 商品剩下的需购买的数量
*/
int standard_num[5] = {0};
/** 初始化 */
for( j = 0; j < 5; j ++ ){
standard_num[j] = index[j];
}
for( j = 0; j < n; j ++ ){
/* 如有任何一种商品的数量不够该优惠条件所需,
* 则放弃使用该优惠条件
*/
if( index[code[special_code[j]]] < special_num[j] )
break;
standard_num[code[special_code[j]]] = index[code[special_code[j]]] - special_num[j];
}
if( j == n ){
/** 动归方程,比较使用该优惠条件前后的价格情况,取较小值 */
if( dp[index[0]][index[1]][index[2]][index[3]][index[4]] >
dp[standard_num[0]][standard_num[1]][standard_num[2]][standard_num[3]][standard_num[4]] + p )
dp[index[0]][index[1]][index[2]][index[3]][index[4]] =
dp[standard_num[0]][standard_num[1]][standard_num[2]][standard_num[3]][standard_num[4]] + p;
}
}
}
printf("%d\n", dp[num[0]][num[1]][num[2]][num[3]][num[4]]);
return 0;
}