[算法]动态规划 多重背包 二进制优化
Posted z354681250
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[算法]动态规划 多重背包 二进制优化相关的知识,希望对你有一定的参考价值。
/*
Name:多重背包 二进制优化 (DP)
Actor:HT
Time:2015年11月2日
Error Reporte:
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#define N 10010
using namespace std;
int dp[100];
int value[N];
int cost[N];
int size[N]; //数量
int n, m; //n个宝石 m大小背包
int main()
int t, i, j, k;
int temp;
while (scanf("%d %d", &n,&m) != EOF)
for (i = 0; i < n; i++)
scanf("%d %d %d", &value[i], &cost[i], &size[i]);
for (i = 0; i < m; i++)
dp[i] = 0; //初始化
for (i = 0; i < n; i++)
if (size[i] * cost[i] >= m) //如果个数足够多,当做完全背包处理
for (j = cost[i]; j <= m; j++)
dp[j] = (dp[j]>dp[j - cost[i]] + value[i]) ? dp[j] : dp[j - cost[i]] + value[i];
else //不够多,那就二进制拆成01背包吧
int div1, div2; //div1是已经看了的小堆(1、2、4...),div2是剩余所有量
div1 = 1;
div2 = size[i];
while (div1 < div2)
for (j = m; j >= div1*cost[i]; j--)
dp[j] = dp[j]>dp[j - div1*cost[i]] + div1*value[i] ? dp[j] : (dp[j - div1*cost[i]] + div1*value[i]);
div2 -= div1;
div1 *= 2;
for (j = m; j >= div2*cost[i]; j--) //剩余的量再补一次
dp[j] = dp[j]>dp[j - div2*cost[i]] + div2*value[i] ? dp[j] : (dp[j - div2*cost[i]] + div2*value[i]);
printf("%d\\n", dp[m]);
return 0;
//dp[j] = (隐含:看了i个宝石,)背包剩余空间j
//dp[j] = maxdp[j] , dp[j-c[i]] + v[i]
//后记:二进制思想
//假设有1000个苹果,现在要取n个苹果,如何取?
//正常的做法应该是将苹果一个一个拿出来,直到n个苹果被取出来。
//又假设有1000个苹果和10只箱子,如何快速的取出n个苹果呢?
//可以在每个箱子中放 2^i (i<=0<=n)个苹果,也就是 1、2、4、8、16、32、64、128、256、489(最后的余数)
//相当于把十进制的数用二进制来表示,取任意n个苹果时,只要推出几只箱子就可以了。
//二进制优化的思路,就是将M个相同物品,堆分成1、2、4、8、...这“几个”大小不等的物品
//通过对这几个堆的取舍,来完成达到拿走n个物品的的最优情况
以上是关于[算法]动态规划 多重背包 二进制优化的主要内容,如果未能解决你的问题,请参考以下文章