二进制思想和多重背包问题
2012-09-07 18:17
246 查看
二进制思想
问题描述:
假设有1000个苹果,现在要取n个苹果,如何取?正常的做法应该是将苹果一个一个拿出来,直到n个苹果被取出来。
又假设有1000个苹果和10只箱子,如何快速的取出n个苹果呢?可以在每个箱子中放 2^i (i<=0<=n)个苹果,也就是 1、2、4、8、16、32、64、128、256、489(最后的余数),相当于把十进制的数用二进制来表示,取任意n个苹果时,只要推出几只箱子就可以了。
多重背包问题
问题描述:
有N种物品和一个容量为V的背包。第 i 种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
问题分析:
很容易想到可以把该问题转化成01背包问题来考虑,把每n[i] 中的每个物品都当成一个独立的物品,而这 n[i] 个物品能够表示的重量其实用 log n[i]个组合后的物品就能表示。
内层循环代码如下:
poj上的1014是一道简单的多重背包问题。http://poj.org/problem?id=1014
源码如下:
View Code
问题描述:
假设有1000个苹果,现在要取n个苹果,如何取?正常的做法应该是将苹果一个一个拿出来,直到n个苹果被取出来。
又假设有1000个苹果和10只箱子,如何快速的取出n个苹果呢?可以在每个箱子中放 2^i (i<=0<=n)个苹果,也就是 1、2、4、8、16、32、64、128、256、489(最后的余数),相当于把十进制的数用二进制来表示,取任意n个苹果时,只要推出几只箱子就可以了。
多重背包问题
问题描述:
有N种物品和一个容量为V的背包。第 i 种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
问题分析:
很容易想到可以把该问题转化成01背包问题来考虑,把每n[i] 中的每个物品都当成一个独立的物品,而这 n[i] 个物品能够表示的重量其实用 log n[i]个组合后的物品就能表示。
内层循环代码如下:
int k, t; k = 1; t = n[i]; while(t > k) { for(j=W; j>=c[i]*k; --j) { f[j] = max(f[j], f[j-c[i]*k] + w[i]*k); } t -= k; k *= 2; } for(j=W; j>=c[i]*t; --j) { f[j] = max(f[j], f[j-c[i]*t] + w[i]*t); }
poj上的1014是一道简单的多重背包问题。http://poj.org/problem?id=1014
源码如下:
View Code
#include <stdio.h> #define max(x, y) ((x)>(y) ? (x) : (y)) int f[80001]; int main() { int c[7]; int i, j; int m = 0; int nHarf = 0; while(scanf("%d %d %d %d %d %d", &c[1], &c[2], &c[3], &c[4], &c[5], &c[6]) ) { if(c[1]==0 && c[2]==0 && c[3]==0 && c[4]==0 && c[5]==0 && c[6]==0) { break; } printf("Collection #%d:\n", ++m); nHarf = c[1]*1 + c[2]*2 + c[3]*3 + c[4]*4 + c[5]*5 + c[6]*6; if(nHarf%2 == 1) { printf("Can't be divided.\n\n"); continue; } else { nHarf /= 2; } for(i=1; i<7; ++i) { if(c[i] == 0) continue; if(c[i]*i > nHarf) { for(j=i; j<=nHarf; ++j) { f[j] = max(f[j], f[j-i] + i); } } else { int k, t; k = 1; t = c[i]; while(t > k) { for(j=nHarf; j>=i*k; --j) { f[j] = max(f[j], f[j-i*k] + i*k); } t -= k; k *= 2; } for(j=nHarf; j>=i*t; --j) { f[j] = max(f[j], f[j-i*t] + i*t); } } } if(f[nHarf] == nHarf) { printf("Can be divided.\n\n"); } else { printf("Can't be divided.\n\n"); } for(i=0; i<=nHarf; ++i) { f[i] = 0; } } return 0; }
相关文章推荐
- 多重背包问题的二进制分解思想
- poj 1014 Dividing(组合数学方法优化/多重背包问题+二进制优化)
- 51Nod 1086 背包问题 V2(二进制多重背包)
- 多重背包问题的二进制分解思想
- 51Nod 1086 背包问题 V2(二进制多重背包)
- 多重背包的二进制分解思想(转载)
- 完全背包问题----思想的理解
- 多重背包问题:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(HDU 2191)(二进制优化)
- 背包问题的解题思想
- 背包问题【01、完全(恰好or不超过)、多重】【尚未整理完】
- ycb的ACM进阶之路 二进制多重背包
- 多部分和问题(多重背包+二进制优化)
- 关于背包问题的二进制优化
- 多重背包的二进制分解思想
- 关于完全背包问题用二进制优化的可行性证明
- *背包问题(01+完全+多重)
- 递归思想即背包问题
- 多重背包的二进制分解思想
- POJ-1276-Cash-Machine 二进制优化多重背包问题
- 背包问题的二进制优化