POJ 1170 0-1背包变形

98 篇文章 1 订阅

0-1背包变形

题意:

​ 有n个物品,每一种物品的属性是:唯一的数字代号,数量,价格。现在有s种优惠,意味着不同的物品搭配会比原来省钱,现在要问最少花多少钱把所有的物品买下。

思路:

​ 把物品当做0-1背包来考虑,即使是优惠组合也是0-1背包,那么可以直接暴力写了。

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

using namespace std;

const int maxn = 105;

struct goods
{
    int code,cnt,price;
}g[maxn];

int n,s;
int dp[6][6][6][6][6];
int p[maxn][maxn*10];
int reduce[maxn];

int judge(int x)
{
    return x >= 0;
}

int main()
{
//    freopen("in.txt","r",stdin);

    while(scanf("%d",&n) != EOF) {
        for(int i = 1;i <= n; i++) {
            scanf("%d%d%d",&g[i].code,&g[i].cnt,&g[i].price);
        }
        scanf("%d",&s);
        for(int i = 1;i <= s; i++) {
            int temp;
            scanf("%d",&temp);
            for(int j = 1;j <= temp; j++) {
                int a,b;
                scanf("%d%d",&a,&b);
                p[i][a] = b;
            }
            scanf("%d",&reduce[i]);
        }
        for(int a = 0;a <= g[1].cnt; a++)
        for(int b = 0;b <= g[2].cnt; b++)
        for(int c = 0;c <= g[3].cnt; c++)
        for(int d = 0;d <= g[4].cnt; d++)
        for(int e = 0;e <= g[5].cnt; e++) {
            dp[a][b][c][d][e] = a*g[1].price + b*g[2].price + c*g[3].price + d*g[4].price + e*g[5].price;
            for(int i = 1;i <= s; i++) {
                int a1 = a - p[i][g[1].code];
                int b1 = b - p[i][g[2].code];
                int c1 = c - p[i][g[3].code];
                int d1 = d - p[i][g[4].code];
                int e1 = e - p[i][g[5].code];
                if(judge(a1) && judge(b1) && judge(c1) && judge(d1) && judge(e1)) {
                    int temp = dp[a1][b1][c1][d1][e1] + reduce[i];
                    dp[a][b][c][d][e] = min(dp[a][b][c][d][e],temp);
                }
            }
        }
        printf("%d\n",dp[g[1].cnt][g[2].cnt][g[3].cnt][g[4].cnt][g[5].cnt]);
    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值