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 时的最少花费(关于购买状态:00032表示第0种物品买2个,第1种物品买3个),则状态转移方程为:

dp[i + product[j].nState] = min(dp[i + product[j].nState], dp[i] + product[j].nPrice)(j是枚举各种物品的物品下标);

#include <cstdio>
#include <cstring>
#include <algorithm>

using std::min;

const int MAXN = 5 + 1;
const int MAXS = 6 * 6 * 6 * 6 * 6;
const int MAX_SIX = 6;
const int MAX_ID = 999 + 1;
const int MAX_OFFER = 99 + 1;

struct PRODUCT
{
    int nId;
    int nNum;
    int nPrice;
    int nState;
} product[MAXN + MAX_OFFER];

int nType;
int dp[MAXS];
int nTargetState;
int nSixPow[MAX_SIX];
int nId2Bit[MAX_ID];

void Init()
{
    nType = 0;
    nTargetState = 0;
}

void GetSixPow()
{
    nSixPow[0] = 1;
    for (int i = 1; i < MAX_SIX; ++i)
    {
        nSixPow[i] = nSixPow[i - 1] * 6;
    }
}

void CompletePack()
{
    memset(dp, 0x3f, sizeof(dp));
    dp[0] = 0;
    for (int i = 0; i < nTargetState; ++i)
    {
        for (int j = 0; j < nType; ++j)
        {
            if (i + product[j].nState > nTargetState) continue;
            dp[i + product[j].nState] = min(dp[i + product[j].nState], dp[i] + product[j].nPrice);
        }
    }
    printf("%d\n", dp[nTargetState]);
}

int main()
{
    int b, s, n;

    GetSixPow();
    while (scanf("%d", &b) == 1)
    {
        Init();
        for (int i = 0; i < b; ++i)
        {
            scanf("%d%d%d", &product[i].nId, &product[i].nNum, &product[i].nPrice);
            product[i].nState = nSixPow[i];
            nTargetState += nSixPow[i] * product[i].nNum;
            nId2Bit[product[i].nId] = i;
        }
        scanf("%d", &s);
        for (int i = 0; i < s; ++i)
        {
            int nId, nCnt;
            product[b + i].nState = 0;
            scanf("%d", &n);
            for (int j = 0; j < n; ++j)
            {
                scanf("%d%d", &nId, &nCnt);
                product[b + i].nState += nSixPow[nId2Bit[nId]] * nCnt;
            }
            scanf("%d", &product[b + i].nPrice);
        }
        nType = b + s;
        CompletePack();
    }
    return 0;
}
时间: 2024-08-24 23:05:25

poj - 1170 - Shopping Offers(状态压缩dp)的相关文章

POJ - 1170 Shopping Offers (五维DP)

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

背包系列练习( 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 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3254 Corn Fields 状态压缩DP

题目链接:http://poj.org/problem?id=3254 思路:状态压缩DP,状态方程为dp[i][j] += (dp[i-1][k]) code: #include <stdio.h> #include <string.h> #define N 500 const int MOD = 100000000; int dp[15][N],ant[N],n,m,k,map[15]; bool ok(int x) { if(x&(x<<1))return

POJ 3691 (AC自动机+状态压缩DP)

题目链接:  http://poj.org/problem?id=3691 题目大意:给定N的致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题思路: 首先说一下AC自动机在本题中的作用. ①字典树部分:负责判断当前0~i个字符组成的串是否包含致病DNA,这部分靠字典树上的cnt标记完成. ②匹配部分:主要依赖于匹配和失配转移关系的计算,这部分非常重要,用来构建不同字符间状态压缩的转移关系(代替反人类的位运算). 这也是必须使用AC自动机而

HDU3768 Shopping(状态压缩DP+spfa)旅行商问题

Shopping Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 577    Accepted Submission(s): 197 Problem Description You have just moved into a new apartment and have a long list of items you need

POJ 3254 Corn Fields(状态压缩DP)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

poj 1185 炮兵阵地(状态压缩dp)

Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不

POJ 3254. Corn Fields 状态压缩DP (入门级)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm