此处有目录↑
在商店中,每一种商品都有一个价格(用整数表示)。例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z 。为了吸引更多的顾客,商店举行了促销活动。
促销活动把一个或多个商品组合起来降价销售,例如:
三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是 12z。 编写一个程序,计算顾客购买一定商品的花费,尽量利用优惠使花费最少。尽管有时候添加其他商品可以获得更少的花费,但是你不能这么做。
对于上面的商品信息,购买三朵花和两个花瓶的最少花费的方案是:以优惠价购买两个花瓶和一朵花(10z),以原价购买两朵花(4z)。
PROGRAM NAME: shopping
INPUT FORMAT:
(file shopping.in)
输入文件包括一些商店提供的优惠信息,接着是购物清单。(最多有5种商品)
第一行 优惠方案的种类数(0 <= s <= 99)。
第二行..第s+1 行 每一行都用几个整数来表示一种优惠方式。第一个整数 n (1 <= n <= 5),表示这种优惠方式由 n 种商品组成。后面 n 对整数 c 和 k 表示 k (1 <= k <= 5)个编号为 c (1 <= c <= 999)的商品共同构成这种优惠,最后的整数 p 表示这种优惠的优惠价(1 <= p <= 9999)。优惠价总是比原价低。
第 s+2 行 这一行有一个整数 b (0 <= b <= 5),表示需要购买 b 种不同的商品。
第 s+3 行..第 s+b+2 行 这 b 行中的每一行包括三个整数:c,k,p。 c 表示唯一的商品编号(1 <= c <= 999),k 表示需要购买的 c 商品的数量(1 <= k <= 5)。p 表示 c 商品的原价(1 <= p <= 999)。最多购买 5*5=25 个商品。
OUTPUT FORMAT:
(file shopping.out)
只有一行,输出一个整数:购买这些物品的最低价格。
2 1 7 3 5 2 7 1 8 2 10 2 7 3 2 8 2 5
14
很开心能够一眼看出来是五维DP,但是实现起来的确有点麻烦
首先是不确定是否会有要购买的物品之外的其他物品,其次是编号如何对应
看了别人的代码后确定套餐内的物品均在购物清单内,可以用下标代表物品数量的物品的编号,可以避免dp时搜索以使下标对应商品编号
觉得初始化和dp过程应该分开,即使初始化放在dp过程中会减少代码量
/* ID: your_id_here PROG: shopping LANG: C++ */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int s,b,c,t[5]; int dp[7][7][7][7][7]; struct Goods { int c,k,p; Goods() { c=k=p=0; } }g[5]; struct Node { int n,k[1001],p; }l[101]; int main() { freopen("shopping.in","r",stdin); freopen("shopping.out","w",stdout); scanf("%d",&s); for(int i=0;i<s;++i) { scanf("%d",&l[i].n); for(int j=0;j<l[i].n;++j) { scanf("%d",&c); scanf("%d",&l[i].k[c]); } scanf("%d",&l[i].p); } scanf("%d",&b); for(int i=0;i<b;++i) scanf("%d%d%d",&g[i].c,&g[i].k,&g[i].p); for(int i=0;i<=g[0].k;++i)//初始化清单上的物品均按照原价购买 for(int j=0;j<=g[1].k;++j) for(int k=0;k<=g[2].k;++k) for(int p=0;p<=g[3].k;++p) for(int q=0;q<=g[4].k;++q) dp[i][j][k][p][q]=i*g[0].p+j*g[1].p+k*g[2].p+p*g[3].p+q*g[4].p; while(s-->0) { for(int i=0;i<5;++i) t[i]=l[s].k[g[i].c]; for(int i=t[0];i<=g[0].k;++i) for(int j=t[1];j<=g[1].k;++j) for(int k=t[2];k<=g[2].k;++k) for(int p=t[3];p<=g[3].k;++p) for(int q=t[4];q<=g[4].k;++q) dp[i][j][k][p][q]=min(dp[i][j][k][p][q],dp[i-t[0]][j-t[1]][k-t[2]][p-t[3]][q-t[4]]+l[s].p); } printf("%d\n",dp[g[0].k][g[1].k][g[2].k][g[3].k][g[4].k]); return 0; }