码迷,mamicode.com
首页 > 其他好文 > 详细

usaco Shopping Offers(多重完全背包)

时间:2015-09-23 00:57:29      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:

 有个人要去超时买东西,超市推出了一些优惠信息,每个优惠信息可以使用多次,每条优惠信息限制了要使用这个优惠信息所需购买的物品种类和每种物品的数量。

 求买下这个人想买得所有物品总共需要的最少花费。

分析之后以优惠券作为物品,以要买的物品总量为容量,花费的钱为价值。

/*
ID: modengd1
PROG: shopping
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <vector>
int indexofcode[1000];// 编号为i的商品离散化后的下标
int buyofindex[5];//编号为i的商品总共买多少
int priceofindex[5];//离散化后的坐标为i的物品的原价
struct offer
{
    int kind,price;//这条优惠信息中包含的商品的种类,这条优惠信息代表的价格
    int code[5];//每种商品的代码
    int num[5];//每种商品限定的个数
};
offer Offers[100];
bool isuseful[100];//下标为i的优惠信息是否可用,如果这条信息中包含了我不需要的商品,则不可用
using namespace std;
int S;//优惠信息的数目
int B;//要买的商品的种类数目
int dp[6][6][6][6][6];
void getinput()//输入
{

    memset(buyofindex,0,sizeof(buyofindex));
    scanf("%d",&S);
    for(int i=0;i<S;i++)
    {
        scanf("%d",&Offers[i].kind);
        for(int j=0;j<Offers[i].kind;j++)
        {
            scanf("%d%d",&Offers[i].code[j],&Offers[i].num[j]);
        }
        scanf("%d",&Offers[i].price);
    }
    scanf("%d",&B);
    int c,k,p;
    for(int i=0;i<B;i++)
    {
        scanf("%d%d%d",&c,&k,&p);
        indexofcode[c]=i;//给物品编号
        buyofindex[i]=k;
        priceofindex[i]=p;
    }

    //判断哪些优惠券不能使用
     memset(isuseful,0x01,sizeof(isuseful));//全部初始化为真
    for(int i=0;i<S;i++)
    {
        for(int j=0;j<Offers[i].kind;j++)
        {
            //优惠信息里的物品有客户不需要的,或者优惠信息里的某个物品的数量限制大于客户要买的数量
            if(indexofcode[Offers[i].code[j]]>=B||buyofindex[indexofcode[Offers[i].code[j]]]<Offers[i].num[j])
            {
                cout<<indexofcode[Offers[i].code[j]]<<‘ ‘<<B<<buyofindex[Offers[i].code[j]]<<‘ ‘<<Offers[i].num[j]<<endl;
                isuseful[i]=false;
                break;
            }
        }
    }
}
void slove()
{
    //初始化所有物品按照原价买时的价格
    for(int a=0;a<=5;a++)
        for(int b=0;b<=5;b++)
            for(int c=0;c<=5;c++)
                for(int d=0;d<=5;d++)
                    for(int e=0;e<=5;e++)
                        dp[a][b][c][d][e]=a*priceofindex[0]+b*priceofindex[1]+c*priceofindex[2]+d*priceofindex[3]+e*priceofindex[4];

    for(int i=0;i<S;i++)
    {
        if(!isuseful[i])
            continue;
        int items[5];
        memset(items,0,sizeof(items));
        for(int j=0;j<Offers[i].kind;j++)
        {
            items[indexofcode[Offers[i].code[j]]]=Offers[i].num[j];
        }
        for(int a=items[0];a<=5;a++)
            for(int b=items[1];b<=5;b++)
                for(int c=items[2];c<=5;c++)
                    for(int d=items[3];d<=5;d++)
                        for(int e=items[4];e<=5;e++)
                            dp[a][b][c][d][e]=min(dp[a][b][c][d][e],dp[a-items[0]][b-items[1]][c-items[2]][d-items[3]][e-items[4]]+Offers[i].price);

    }
    cout<<dp[buyofindex[0]][buyofindex[1]][buyofindex[2]][buyofindex[3]][buyofindex[4]]<<endl;
}
int main()
{
    freopen("shopping.in","r",stdin);
    freopen("shopping.out","w",stdout);
    getinput();
    slove();
    return 0;
}

  

usaco Shopping Offers(多重完全背包)

标签:

原文地址:http://www.cnblogs.com/modengdubai/p/4830889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!