USACO3.3--Shopping Offers

如果我们将每一种优惠方案看成一种物品,那么这个问题就可以转换成背包问题,我们可以定义dp[a1][a2][a3][a4][a5]表示购买第一到第五中物品ai个时的最小代价,然后转移方程类似于完全背包dp[a1][a2][a3][a4][a5]=min(dp[a1-st[i].num[a1]][a2-st[i].num[a2]…[a5-st[i].num[a5]);但是这样还不够,因为根据题目要求其实是要求将背包填满的情况下的最下代价,这时有两种处理方法,第一种就是将每一种要购买的物品作为一种数量为1的方案进行填充,这样就可以保证总能将背包填满.第二种是我的思路,先初始化背包的所有可能为其应付的代价,然后再用优惠方案去填充,这样也可以保证将背包填满.

代码如下:

/*
ID: 15674811
LANG: C++
TASK: shopping
*/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n,m;
typedef struct node
{
     int num[1010];
     int p;
     node()
     {
          memset(num,0,sizeof(num));
     }
}S;
S st[1010];

typedef struct nd
{
     int num,cnt,p;
}A;
A a[10];
int dp[6][6][6][6][6];

void Init()
{
     for(int i1=0;i1<=5;i1++)
        for(int i2=0;i2<=5;i2++)
            for(int i3=0;i3<=5;i3++)
                for(int i4=0;i4<=5;i4++)
                   for(int i5=0;i5<=5;i5++)
                       dp[i1][i2][i3][i4][i5]=i1*a[1].p+i2*a[2].p+i3*a[3].p+i4*a[4].p+i5*a[5].p;
}

int main()
{
      //freopen("shopping.in","r",stdin);
      //freopen("shopping.out","w",stdout);
      freopen("in.txt","r",stdin);
      int n,m;
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
      {
            int cnt;
            scanf("%d",&cnt);
            for(int j=0;j<cnt;j++)
            {
                   int x,y;
                   scanf("%d%d",&x,&y);
                   st[i].num[x]=y;
            }
            scanf("%d",&st[i].p);
      }
      scanf("%d",&m);
      memset(a,0,sizeof(a));
      for(int i=1;i<=m;i++)
             scanf("%d%d%d",&a[i].num,&a[i].cnt,&a[i].p);
     Init();
     for(int i=1;i<=n;i++)
      {
          int m1=st[i].num[a[1].num];
          int m2=st[i].num[a[2].num];
          int m3=st[i].num[a[3].num];
          int m4=st[i].num[a[4].num];
          int m5=st[i].num[a[5].num];
          for(int i1=m1;i1<=a[1].cnt;i1++)
               for(int i2=m2;i2<=a[2].cnt;i2++)
                   for(int i3=m3;i3<=a[3].cnt;i3++)
                        for(int i4=m4;i4<=a[4].cnt;i4++)
                             for(int i5=m5;i5<=a[5].cnt;i5++)
                                    dp[i1][i2][i3][i4][i5]=min(dp[i1][i2][i3][i4][i5],dp[i1-m1][i2-m2][i3-m3][i4-m4][i5-m5]+st[i].p);
      }
    printf("%d\n",dp[a[1].cnt][a[2].cnt][a[3].cnt][a[4].cnt][a[5].cnt]);
  return 0;
}
时间: 2024-11-06 09:57:56

USACO3.3--Shopping Offers的相关文章

Shopping Offers

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

洛谷P2732 商店购物 Shopping Offers

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

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

背包系列练习( 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 Shopping Offers(多重完全背包)

有个人要去超时买东西,超市推出了一些优惠信息,每个优惠信息可以使用多次,每条优惠信息限制了要使用这个优惠信息所需购买的物品种类和每种物品的数量. 求买下这个人想买得所有物品总共需要的最少花费. 分析之后以优惠券作为物品,以要买的物品总量为容量,花费的钱为价值. /* ID: modengd1 PROG: shopping LANG: C++ */ #include <iostream> #include <stdio.h> #include <memory.h> #in

[Leetcode] DP-- 638. Shopping Offers

In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price. You are given the each item's price, a se

POJ - 1170 Shopping Offers (五维DP)

题目大意:有一个人要买b件商品,给出每件商品的编号,价格和数量,恰逢商店打折.有s种打折方式.问怎么才干使买的价格达到最低 解题思路:最多仅仅有五种商品.且每件商品最多仅仅有5个,所以能够用5维dp来表示.每一个维度都代表一件商品的数量 打折的方式事实上有b + s种.将每种商品单件卖的也算一种打折方式 这题有个坑点,就是b或者s有可能为0 #include<cstdio> #include<cstring> #include<algorithm> #include&l

poj - 1170 - Shopping Offers(状态压缩dp)

题意:b(0 <= b <= 5)种物品,每种有个标号c(1 <= c <= 999),有个需要购买的个数k(1 <= k <=5),有个单价p(1 <= p <= 999),有s(0 <= s <= 99)种组合优惠方案,问完成采购最少需要多少钱. 题目链接:http://poj.org/problem?id=1170 -->>已有b种物品,再将每种优惠分别看成一种新物品,剩下就是完全背包问题了.. 设dp[i]表示购买状态为 i

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

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