题意:
给在商店里要买的商品的种类,数量,价格,和一些组合购买选项(如同时买2个a,1个b,只要x元),求最小花费。
分析:
因为要买的商品种类数b是变量(b<=5),一开始还想背包的维数不确定怎么搞啊,后来发现按5维开背包就可以了,接下来就是完全背包了。
代码:
//poj 1170
//sep9
#include <iostream>
using namespace std;
int b,c,k,p,s;
int dp[8][8][8][8][8];
int tot_idx[8];
int idx[1024];
struct PRODUCT
{int num,price,c;
}product[1024];struct OFFER
{int n,cost;pair<int,int> item[8];
}offer[128];int main()
{scanf("%d",&b);for(int i=0;i<5;++i){if(i<b)scanf("%d%d%d",&c,&k,&p);elsec=1000+i,k=0,p=0;product[i].num=k,product[i].price=p,product[i].c=c;idx[c]=i;} scanf("%d",&s);for(int i=0;i<s;++i){scanf("%d",&offer[i].n);for(int j=0;j<offer[i].n;++j)scanf("%d%d",&offer[i].item[j].first,&offer[i].item[j].second);scanf("%d",&offer[i].cost);}for(int i=0;i<b;++i){offer[s].n=1;offer[s].cost=product[i].price;offer[s].item[0].first=product[i].c;offer[s].item[0].second=1;++s;}memset(dp,0x40,sizeof(dp));dp[0][0][0][0][0]=0;for(int i=0;i<s;++i)for(int a=0;a<=product[0].num;++a)for(int b=0;b<=product[1].num;++b)for(int c=0;c<=product[2].num;++c)for(int d=0;d<=product[3].num;++d)for(int e=0;e<=product[4].num;++e){int cost[8],val;cost[0]=cost[1]=cost[2]=cost[3]=cost[4]=0;for(int j=0;j<offer[i].n;++j){int x=offer[i].item[j].first;int y=offer[i].item[j].second;cost[idx[x]]+=y; } if(a>=cost[0]&&b>=cost[1]&&c>=cost[2]&&d>=cost[3]&&e>=cost[4]){int t=dp[a-cost[0]][b-cost[1]][c-cost[2]][d-cost[3]][e-cost[4]]+offer[i].cost;dp[a][b][c][d][e]=min(dp[a][b][c][d][e],t);}}printf("%d",dp[product[0].num][product[1].num][product[2].num][product[3].num][product[4].num]); return 0;
}