zoukankan      html  css  js  c++  java
  • HDU 1170 Shopping Offers 离散+状态压缩+完全背包

    题目链接:

    http://poj.org/problem?id=1170

    Shopping Offers

    Time Limit: 1000MS
    Memory Limit: 10000K
    #### 问题描述 > In a shop each kind of product has a price. For example, the price of a flower is 2 ICU (Informatics Currency Units) and the price of a vase is 5 ICU. In order to attract more customers, the shop introduces some special offers. > A special offer consists of one or more product items for a reduced price. Examples: three flowers for 5 ICU instead of 6, or two vases together with one flower for 10 ICU instead of 12. > Write a program that calculates the price a customer has to pay for certain items, making optimal use of the special offers. That is, the price should be as low as possible. You are not allowed to add items, even if that would lower the price. > For the prices and offers given above, the (lowest) price for three flowers and two vases is 14 ICU: two vases and one flower for the reduced price of 10 ICU and two flowers for the regular price of 4 ICU.

    输入

    Your program is to read from standard input. The first line contains the number b of different kinds of products in the basket (0 <= b <= 5). Each of the next b lines contains three values c, k, and p. The value c is the (unique) product code (1 <= c <= 999). The value k indicates how many items of this product are in the basket (1 <= k <= 5). The value p is the regular price per item (1 <= p <= 999). Notice that all together at most 5*5=25 items can be in the basket. The b+2nd line contains the number s of special offers (0 <= s <= 99). Each of the next s lines describes one offer by giving its structure and its reduced price. The first number n on such a line is the number of different kinds of products that are part of the offer (1 <= n <= 5). The next n pairs of numbers (c,k) indicate that k items (1 <= k <= 5) with product code c (1 <= c <= 999) are involved in the offer. The last number p on the line stands for the reduced price (1 <= p <= 9999). The reduced price of an offer is less than the sum of the regular prices.

    输出

    Your program is to write to standard output. Output one line with the lowest possible price to be paid.

    样例输入

    2
    7 3 2
    8 2 5
    2
    1 7 3 5
    2 7 1 8 2 10

    样例输出

    14

    题意

    告诉你每类产品的单价,和打算购买的数量。现在有些优惠活动,买一些特定数量的商品组合能够优惠,问你如何用最少的钱买到需要购买的商品。

    题解

    dp[i][j][k][l][m]代表购买了i个商品0...m个商品4,需要花的最少的money,然后每个优惠活动和单价都可以看作转移边。前面那个状态可以用六进制压缩下状态。

    这样转化成了一个完全背包的额问题了。

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<sstream>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=7800;
    
    struct In {
        int id,c,v;
        bool operator < (const In& tmp) const {
            return id<tmp.id;
        }
    } in[11];
    
    int dp[maxn],a[11],b[11],xp[11];
    
    int main() {
        xp[0]=1; for(int i=1;i<11;i++) xp[i]=xp[i-1]*6;
        int n,m;
        while(scf("%d",&n)==1) {
            VI ha;
            VPII arr;
            for(int i=0; i<n; i++) {
                scf("%d%d%d",&in[i].id,&in[i].c,&in[i].v);
                ha.pb(in[i].id);
            }
    
            sort(all(ha));
            sort(in,in+n);
    
            int last=0;
            for(int i=0;i<n;i++){
                last+=xp[i]*in[i].c;
                arr.pb(mkp(xp[i],in[i].v));
            }
    
            scf("%d",&m);
            for(int i=0;i<m;i++){
                int cnt; scf("%d",&cnt);
                int stat=0;
                while(cnt--){
                    int id,c;
                    scf("%d%d",&id,&c);
                    int p=lower_bound(all(ha),id)-ha.begin();
                    stat+=c*xp[p];
                }
                int v; scf("%d",&v);
                arr.pb(mkp(stat,v));
            }
    
            clr(dp,-1);
            dp[0]=0;
            for(int i=1;i<=last;i++){
                for(int j=0;j<arr.sz();j++){
                    int stat=arr[j].X,v=arr[j].Y;
                    if(i-stat>=0&&dp[i-stat]>=0){
                        if(dp[i]==-1) dp[i]=dp[i-stat]+v;
                        else dp[i]=min(dp[i],dp[i-stat]+v);
                    }
                }
            }
    
            prf("%d
    ",dp[last]);
    
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    微信java封装
    解决PowerDesigner 生成Sql2005-2012 找不到sysproperties表的问题
    ASP.net解析JSON例子
    c# 遍历子控件,比如Form下的group,或者panel
    修改sql2005字段
    清除grid内容的列
    sql 2000以及2005以上获取数据库中所有的表(不包括系统表)
    获取SqlServer2005表结构(字段,主键,外键,递增,描述)
    SQL SERVER 数据库实用SQL语句
    查找所有页面中的按钮
  • 原文地址:https://www.cnblogs.com/fenice/p/5922297.html
Copyright © 2011-2022 走看看