现在的位置: 首页 > 综合 > 正文

【動態規劃】逃亡的準備

2013年10月10日 ⁄ 综合 ⁄ 共 1320字 ⁄ 字号 评论关闭
题目描述

【问题描述】
在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品,现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常地感谢你。
出自:宜昌一中
【数据规模】
对于30%的数据
1<=v<=500
1<=n<=2000
1<=m<=10
1<=w<=20
1<=s<=100

对于100%的数据
1<=v<=500
1<=n<=2000
1<=m<=5000
1<=w<=20
1<=s<=100
输入格式

【输入】
(1)第一行有2个整数,物品种数n和背包装载体积v。
(2)2行到n+1行每行3个整数,为第i种物品的数量m、体积w、价值s。.
输出格式

【输出】
仅包含一个整数,即为能拿到的最大的物品价值总和。
样例输入
【输入样例】 2 10 3 4 3 2 2 5
样例输出
【输出样例】 13 【注释】选第一种一个,第二种两个。结果为3*1+5*2=13 

簡單的一道多重背包,不再多說。
注意枚舉的時候,分成兩種情況:
若某個物品數量乘以單位體積超過背包總容量,則當成完全背包處理;否則將這個物品的數量拆成二進制數,再按零壹背包的方式枚舉這個二進制數的每一位。
ACCode:

#include <cstdio>
#include <cstring>
#include <bitset>
#include <cstdlib>

using std::max;

const char fi[] = "rqnoj98.in";
const char fo[] = "rqnoj98.out";
const int maxN = 2010;
const int maxV = 510;
const int MAX = 0x3fffff00;
const int MIN = -0x3fffff00;

int f[maxV];
int a[maxN];
int w[maxN];
int v[maxN];
int n, m;

  void init_file()
  {
    freopen(fi, "r", stdin);
    freopen(fo, "w", stdout);
  }
    
  void readdata()
  {
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n + 1; ++i)
      scanf("%d%d%d", a + i, w + i, v + i);
  }
  
  void work()
  {
    for (int i = 1; i < n + 1; ++i)
    {
      if (a[i] * w[i] >= m)
       for (int j = w[i]; j < m + 1; ++j)
        f[j] = max(f[j], f[j - w[i]] + v[i]);
      else
      {
        for (int k = 1; k < a[i]; k <<= 1)
        {
          for (int j = m; j >= k * w[i]; --j)
            f[j] = max(f[j], f[j - k * w[i]]
              + k * v[i]);
          a[i] -= k;
        }
        for (int j = m; j >= a[i] * w[i]; --j)
          f[j] = max(f[j], f[j - a[i] * w[i]]
            + a[i] * v[i]);
      }
    }
    printf("%d", f[m]);
  }
  
int main()
{
  init_file();
  readdata();
  work();
  exit(0);
}

抱歉!评论已关闭.