• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
井_中窥月
万物美好,我在中央
博客园    首页    新随笔    联系   管理    订阅  订阅
背包模板

  

/*
多重背包模板

【若要求恰好装满,初始化时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

 

posted on 2015-08-19 19:08  井_中窥月  阅读(191)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3