链接:点击打开链接
题意:给定一个含有n种商品的订单,给出订单内每个物品的初始价格和需要购买的数量,再给出m种套餐,这些组合会得到便宜的价格,最后怎样搭配使得总价格最少。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; int dp[500005],HASH[1005]; int SIX[10]={1,6,36,216,1296,7776,46656,279936}; struct node{ int has,num,val; }s[205]; int main(){ //因为最多有五种物品,因此 int b,k,m,x,y,i,j,ans,tmp,NUM; //将每种物品和套餐用六进制 while(scanf("%d",&b)!=EOF){ //进行状态压缩 ans=NUM=0; memset(HASH,-1,sizeof(HASH)); for(i=0;i<b;i++){ scanf("%d%d%d",&tmp,&s[i].num,&s[i].val); s[i].has=SIX[i]; HASH[tmp]=SIX[i]; ans+=s[i].num*s[i].val; NUM+=SIX[i]*s[i].num; //将六进制总数作为背包容量 s[i].num=SIX[i]; //将每个物品的重量变为六进制 } //所表示的数 scanf("%d",&m); for(i=0;i<m;i++){ scanf("%d",&k); while(k--){ scanf("%d%d",&x,&y); if(HASH[x]==-1) continue; s[i+b].num+=HASH[x]*y; //将套餐变为六进制数 } scanf("%d",&s[i+b].val); } memset(dp,INF,sizeof(dp)); dp[0]=0; for(i=0;i<b+m;i++) for(j=s[i].num;j<=NUM;j++) //直接转换成完全背包 dp[j]=min(dp[j],dp[j-s[i].num]+s[i].val); printf("%d\n",min(ans,dp[NUM])); } return 0; }