poj 1170 Shopping Offers 完全背包

本文针对一种特定的商品组合购买问题进行了解析,该问题涉及多种商品及其不同的组合优惠方案。文章通过实例展示了如何使用编程方法解决此类问题,采用的是完全背包问题的思路,并通过多维数组来表示不同商品的数量状态。
摘要由CSDN通过智能技术生成

题意:

给在商店里要买的商品的种类,数量,价格,和一些组合购买选项(如同时买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);
		else
			c=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;	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值