题目背景
在商店中,每一种商品都有一个价格(用整数表示)。例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z 。为了吸引更多的顾客,商店举行了促销活动。
题目描述
促销活动把一个或多个商品组合起来降价销售,例如:
三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是 12z。 编写一个程序,计算顾客购买一定商品的花费,尽量利用优惠使花费最少。尽管有时候添加其他商品可以获得更少的花费,但是你不能这么做。
对于上面的商品信息,购买三朵花和两个花瓶的最少花费的方案是:以优惠价购买两个花瓶和一朵花(10z),以原价购买两朵花(4z)。
输入输出格式
输入格式:
输入文件包括一些商店提供的优惠信息,接着是购物清单。(最多有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 个商品。
输出格式:
只有一行,输出一个整数:购买这些物品的最低价格。
商品的种类不超过五种,每种商品的个数不超过五个,那么可以设dp(a1,a2,a3,a4,a5)为五种商品分别买a1,a2,a3,a4,a5种时的最小花销(对于所有数据可以假设都是有五种商品,只是有的商品需求量是0而已),边界自然就是当五个数都是0的时候,花销为0,对于每一种情况的计算可以依次尝试枚举所有的优惠方案(如果数量够的话),再枚举单个购买的方案,这样推到下一层,由这个思路很容易得到递推公式,写记忆化搜索即可,还有一点是商品的编号不是1~5,而是1000内的5的整数,可以写一个ID函数进行映射(我的习惯),剩下的就是注意细节就OK啦
#include<iostream> #include<cstring> #include<vector> using namespace std; struct CH{ ]; int pr; }; ][][][][],v[][][][][]; ],counter=,yj[],need[]; int S,b; vector<CH> ch; int A(int a1,int a2,int a3,int a4,int a5){ if(v[a1][a2][a3][a4][a5]) return dp[a1][a2][a3][a4][a5]; v[a1][a2][a3][a4][a5]=; int& ans=dp[a1][a2][a3][a4][a5]; ; ans=<<; ;i<S;i++){ ]&&a2>=ch[i].s[]&&a3>=ch[i].s[]&&a4>=ch[i].s[]&&a5>=ch[i].s[]) ans=min(ans,A(a1-ch[i].s[],a2-ch[i].s[],a3-ch[i].s[], a4-ch[i].s[],a5-ch[i].s[])+ch[i].pr); } ,a2,a3,a4,a5)+yj[]); ,a3,a4,a5)+yj[]); ,a4,a5)+yj[]); ,a5)+yj[]); )+yj[]); return ans; } int ID(int x) { if(book[x]) return book[x]; return book[x]=++counter; } int main() { memset(book,,sizeof(book)); int n,c,k; cin>>S; ;i<=S;i++){ cin>>n; CH da; ;i<=;i++) da.s[i]=; ;j<=n;j++){ cin>>c>>k;da.s[ID(c)]=k; } cin>>da.pr; ch.push_back(da); } cin>>b; memset(yj,,sizeof(yj)); memset(need,,sizeof(need)); ;i<=b;i++){ int c,k,p; cin>>c>>k>>p; yj[ID(c)]=p; need[ID(c)]=k; } cout<<A(need[],need[],need[],need[],need[]); ; }