码迷,mamicode.com
首页 > 其他好文 > 详细

背包模板

时间:2015-08-19 22:37:02      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

  

技术分享
/*
多重背包模板

【若要求恰好装满,初始化时f[1...V] = -INF(求最大)或INF(求最小),f[0] = 0】

【若费用==价值时,如硬币能组成多少钱,用背包做时,f[i(费用)] 必定 == i(最大价值) (设能组成i元)  ,因为能组成i元。费用为i时,最大价值若少于i的x的话与能组成i元,矛盾(存在比x大的i),所以必定等于i元,如HDU2844】
*/
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cctype>
#include <cstring>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <algorithm>

using namespace std;
//Constant Declaration
/*--------------------------*/
//#define LL long long
#define LL __int64
const int M=110;
const int INF=1<<30;
const double EPS = 1e-11;
const double PI = acos(-1.0);
/*--------------------------*/
// some essential funtion
/*----------------------------------*/
void Swap(int &a,int &b){ int t=a;a=b;b=t; }
int Max(int a,int b){ return a>b?a:b; }
int Min(int a,int b){ return a<b?a:b; }
int Gcd(int a,int b){ while(b){b ^= a ^=b ^= a %= b;} return a; }
/*----------------------------------*/
//for (i = 0; i < n; i++)
/*----------------------------------*/

int c[M], w[M], n1[M];//c:费用 w:价值 n1:数量
int f[M];//f[与V有关],c和w[与n]有关
int v, V, V1;//V:容量 V1:容量2

//01背包
void ZeroOnePack(int c, int w)
{
    for (int v = V; v >= c; v--)
    {
        f[v] = Max(f[v], f[v-c] + w);
    }
}

//完全背包
void CompletePack(int c, int w)
{
    for (int v = c; v <= V; v++)
    {
        f[v] = Max(f[v], f[v-c] + w);
    }
}

//多重背包,二进制。
void MultiplePack(int c, int w, int n1)
{
    if (c * n1 >= V)
    {
        CompletePack(c, w);
    }
    else
    {
        int k = 1;
        while (k < n1)
        {
            ZeroOnePack(k*c, k*w);
            n1 -= k;
            k <<= 1;
        }
        ZeroOnePack(n1*c, n1*w);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t, case1 = 0;
    scanf("%d", &t);
    int n, m;//n:物品种数
    int i, j;

    //scanf("%d%d", &n, &m);
    while (t--)
    {
        scanf("%d%d", &V, &n);
        for (i = 1; i <= n; i++)
        {
            scanf("%d%d%d", &c[i], &w[i], &n1[i]);

        }

        memset(f, 0, sizeof(f));

        for (i = 1; i <= n; i++)
        {
            MultiplePack(c[i], w[i], n1[i]);
        }

        printf("%d\n", f[V]);

    }

    return 0;
}
View Code

 

背包模板

标签:

原文地址:http://www.cnblogs.com/sunus/p/4743138.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!