usaco Shopping Offers(多重完全背包)

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

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

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

/*
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;
}

  

时间: 2024-10-13 15:06:47

usaco Shopping Offers(多重完全背包)的相关文章

背包系列练习( hdu 2844 Coins &amp;&amp; hdu 2159 &amp;&amp; poj 1170 Shopping Offers &amp;&amp; hdu 3092 Least common multiple &amp;&amp; poj 1015 Jury Compromise)

作为一个oier,以及大学acm党背包是必不可少的一部分.好久没做背包类动规了.久违地练习下-.- dd__engi的背包九讲:http://love-oriented.com/pack/ 鸣谢http://blog.csdn.net/eagle_or_snail/article/details/50987044,这里有大部分比较有趣的dp练手题. hdu 2844 Coins 多重背包 就是一个10w的多重背包,每个物品的cost同时也作为value去做背包,我们求的是每个容量下的价值,所以没

【POJ 1170】 Shopping Offers [动态规划 状态压缩 背包][离散化]

POJ - 1170 Shopping Offers 放假打题 sufu 看完题我是懵比的 这....  emmmmm   瓜想了半个小时之后我选择狗带 然后点开链接 装压+dp!!!!哦!!!!!!巧妙!!!! 就先把目标状态还有各个优惠的状态处理好 然后就是一个完全背包处理用优惠 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int S=100+5,N=10,P=10000+5,C=1000+5; 4 int sale[S

USACO 3.3 Shopping Offers

Shopping OffersIOI'95 In a certain shop, each kind of product has an integer price. For example, the price of a flower is 2 zorkmids (z) and the price of a vase is 5z. In order to attract more customers, the shop introduces some special offers. A spe

洛谷P2732 商店购物 Shopping Offers

P2732 商店购物 Shopping Offers 23通过 41提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交  讨论  题解 最新讨论 暂时没有讨论 题目背景 在商店中,每一种商品都有一个价格(用整数表示).例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z .为了吸引更多的顾客,商店举行了促销活动. 题目描述 促销活动把一个或多个商品组合起来降价销售,例如: 三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是

Shopping Offers

Shopping Offers 在商店中,每一种商品都有一个价格(用整数表示).例如,一朵花的价格是 2 zorkmids (z),而一个花瓶的价格是 5z .为了吸引更多的顾客,商店举行了促销活动. 促销活动把一个或多个商品组合起来降价销售,例如: 三朵花的价格是 5z 而不是 6z, 两个花瓶和一朵花的价格是 10z 而不是 12z. 编写一个程序,计算顾客购买一定商品的花费,尽量利用优惠使花费最少.尽管有时候添加其他商品可以获得更少的花费,但是你不能这么做. 对于上面的商品信息,购买三朵花

Crazy Shopping(拓扑排序+完全背包)

Crazy Shopping(拓扑排序+完全背包) Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C.P), Kawashiro Nitori decides to buy a lot of rare things to celebrate. Kawashiro Nitori is a very shy kappa (a type of water sprite that live in rivers) a

POj 1170 Shopping Offers(变形背包+进制优化) 100

商店买东西会有优惠政策,使用优惠政策使顾客花的钱尽可能的少. 这道题很有现实背景啊,起初看这道题想的是用规则去优化各种组合情况的物品,并没有想到用背包.因为没有做过"规则"这种物品 还有一点就是接收输入信息的时候若用高维数组很难控制,当时竟然写出了int (*it)[5][5][5][5] 这种东西. 这时,进制优化发挥作用了,其思想类似于康托展开,且因为这个问题并不是直接将位置映射到数集,而是各个不同物品的映射.六进制就够用了.将各个物品映射到一个六进制数字中的每一位,一位上的数字0

USACO Training Section 3.3 Shopping Offers

拿给出的每种方案作为一种物品其他的单卖的物品也作为一种物品 拿它们去跑背包就行 注意编号对应上就行 代码: #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cctype> #include <cstdio> #include <locale> #include <map> using

USACO Money Systems Dp 01背包

一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V; ++j){ if(i - a[j] > 0){ dp[i] += dp[i - a[j]]; } } } 状态存在冗余, 输出的时候答案肯定不对 但只需要改一下两个for循环的顺序即可. Source Code: /* ID: wushuai2 PROG: money LANG: C++ */ //