【多重背包模板】poj 1014

#include <iostream>
#include <stdio.h>
#include <cstring>
#define INF 100000000
using namespace std;
int f[240005];  //f[j]相当于f[i][j]: 考虑1...i个物品,恰好放到容量为j,所能达到的最大价值
int v; //背包容量
void complete_pack(int *dp, int c, int w)
{
    for(int i = c; i <= v; i++)
        dp[i] = max(dp[i], dp[i - c] + w);
}
void zeroone_pack(int *dp, int c, int w)
{
    for(int i = v; i >= c; i--)
        dp[i] = max(dp[i], dp[i - c] + w);
} 

void mutiple_pack(int *dp, int c, int w, int m)
{
    if(c * m >= v)
    {
        complete_pack(dp, c, w);
        return;
    }
    int k = 1;
    while(k < m)
    {
        zeroone_pack(dp, k * c, k * w);
        m = m - k;
        k = 2 * k;
    }
    zeroone_pack(dp, c * m, w * m);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int sum, i, c[7], w[7], m[7],cas = 0;
    while(scanf("%d%d%d%d%d%d",&m[1],&m[2],&m[3],&m[4],&m[5],&m[6]))
    {
        if(m[1]==0 && m[2]==0 && m[3]==0 && m[4]==0 && m[5]==0 && m[6]==0)
        break;
        sum = 0;
        for(i = 1; i <= 6; i++)
        {
            c[i] = w[i] = i;
            sum += c[i] * m[i];
        }
        printf("Collection #%d:\n", ++cas);
        if(sum & 1)
            puts("Can‘t be divided.\n");
        else
        {
            sum /= 2;
            v = sum;
            for(i = 1; i <= sum; i++)
                  f[i] = -INF;
            f[0] = 0;
            for(i = 1; i <= 6; i++)
                  mutiple_pack(f, c[i], w[i], m[i]);
            if(f[v] < 0)
                puts("Can‘t be divided.\n");
            else
                puts("Can be divided.\n");
        }
    }
    return 0;
}
时间: 2024-10-07 09:42:28

【多重背包模板】poj 1014的相关文章

多重背包 (poj 1014)

题目:Dividing 题意:6种重量的的石头,每个给定数量,用总重的一半去装,问能否装满. #include <iostream> #include <algorithm> #include <stdlib.h> #include <time.h> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include

多重背包模板

/** * 多重背包: * 有N种物品和一个容量为V的背包.第i种物品最多有Mi件可用, * 每件耗费的空间是Ci,价值是Wi. * 求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大. */ #include <stdio.h> #include <string.h> int max(int a, int b){ if (a > b)return a; return b; } #define maxn 100005 int c[maxn], w

HDU 2844 多重背包模板

给出n个数和m 每个数给出出现次数和价值,问任意组合组成不大于M的价值,共能产生多少个数 多重背包的的二进制优化写法  模板mark一下 二进制优化原理: 1.2.4可以组合出所有小于8的数: 1.2.4.8可以组合出所有小于16的数: 1.2.4.8.16可以组合出所有小于32的数: -- #include "stdio.h" #include "string.h" int n,m; int dp[100010]; void complete_pack(int v

hdu2844Coins(多重背包模板)

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 20860    Accepted Submission(s): 8198 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One

hdu2844 多重背包模板

01 背包 有n 种不同的物品,每个物品有两个属性,size 体积,value 价值,现在给一个容量为 w 的背包,问最多可带走多少价值的物品. int f[w+1]; //f[x] 表示背包容量为x 时的最大价值 for (int i=0; i<n; i++) for (int j=w; j>=size[i]; j--) f[j] = max(f[j], f[j-size[i]]+value[i]); //逆序 完全背包 如果物品不计件数,就是每个物品有无数件的话,稍微改下即可 for (i

解题报告:hdu2191汶川地震 - 多重背包模板

2017-09-03 17:01:36 writer:pprp 这是一道多重背包裸题 - 记得是从右向左进行,还有几点需要注意啊,都在代码中表示出来了 代码如下: /* @theme:hdu2191 汶川地震 @writer:pprp @begin:16:25 @end:16:59 @declare:多重背包问题 @error:方向是从左向右进行 @date:2017/9/3 */ #include <bits/stdc++.h> using namespace std; int M, N;/

hpu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 【多重背包模板】

悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19561    Accepted Submission(s): 8280 Problem Description 急!灾区的食物依然短缺! 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,

01、完全、多重背包模板

背包问题: 背包总容量为W,有n件重量为weight[i],权值为value[i]的物品 1.01背包: 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 1 void ZeroOnePack (int weight,int value) 2 { 3 for (int w = W; w >= weight; w--) 4 dp[w] = max(dp[w - weight] + value, dp[w]); 5 } 2.完全背包: 每件物品有无限多个. void Complet

hdu 2844 Coins 多重背包模板题 ,二进制优化。据说是楼教主的男人八题之一

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8052    Accepted Submission(s): 3291 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One