多重背包问题的特点是物品数量可以大于1但是有限制。状态定义与01背包一致。

多重背包的解法有多种,复杂度也各不相同。

对于物品数Ci较大的数据,可以采取二进制数进行优化(就是这样,别问就是baidu!)

如何理解多重背包的二进制优化?

使得每种物品的转移次数由O(MxCi)变为O(Mxlog(Ci))

f[i]=f[i] | f[i-a[i]] | …| f[i-a[i]xc[i]](a[i]为物品价值,c[i]为物品数量)

二进制优化后令W[i]=a[i]xc[i](c[i]被二进制分拆)

/*
Memory: 3508K Time: 329MS
Language: Java Result: Accepted
*/

实现见代码:

 package poj.ProblemSet;

 import java.util.Scanner;

 public class poj1014 {
public static final int MAXN = 400000;
public static boolean[] f = new boolean[MAXN];
public static int[] w = new int[100]; public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
for (int Case = 0; cin.hasNext(); ) {
int value = 0, cnt = 0;
boolean flag = false;
for (int i = 1; i <= 6; i++) {
int val = cin.nextInt();
value += val * i;
for (int j = 1, x = 0; val > 0; j *= 2) {
x = Math.min(j, val);
w[++cnt] = i * x;
val -= x;
}
}
if (value == 0) break;
System.out.println("Collection #" + (++Case) + ":");
if (value % 2 == 0) {
f[0] = true;
for (int i = 1; i < MAXN; i++) f[i] = false;
for (int i = 1; i <= cnt; i++)
for (int j = value / 2; j >= w[i]; j--)
f[j] |= f[j - w[i]];
flag = true;
}
System.out.println((!flag?"Can't":(f[value/2]?"Can":"Can't"))+" be divided.");
System.out.println();
}
}
}

 PS:另外一种O(VN)的方法是用数据结构单调队列优化!!!Orz

/*
Memory: 6064K Time: 282MS
Language: Java Result: Accepted
*/
 package poj.ProblemSet;

 import java.util.Scanner;

 public class poj1014 {
public static final int MAXN = 400000;
public static int[] queue = new int[MAXN];
public static boolean[] f = new boolean[MAXN];
public static int[] c = new int[7];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
for (int Case = 0; cin.hasNext(); ) {
int value = 0;
boolean flag = false;
for (int i = 1; i <= 6; i++) {
c[i] = cin.nextInt();
value += i * c[i];
}
if (value == 0) break;
System.out.println("Collection #" + (++Case) + ":");
if (value % 2 == 0) {
f[0] = true;
for (int i = 1; i <= value / 2; i++) f[i] = false;
for (int i = 1, x = 0; i <= 6; i++) {
x = i * c[i];
for (int j = 0; j < i; j++)
if (f[j]) queue[j] = j;
else queue[j] = -MAXN;
for (int j = i; j <= value / 2; j++)
if (f[j]) queue[j] = j;
else {
queue[j] = queue[j - i];
if (queue[j - i] + x >= j) f[j] = true;
}
}
flag = true;
}
System.out.println((!flag?"Can't":(f[value/2]?"Can":"Can't"))+" be divided.");
System.out.println();
}
}
}

Java-POJ1014-Dividing的更多相关文章

  1. POJ1014 Dividing

    题目来源:http://poj.org/problem?id=1014 题目大意: Marsha和Bill拥有一些弹珠.但是这些弹珠的价值不一样.每个弹珠的价值都是1到6之间的自然数.他们希望把这些弹 ...

  2. 【DP|多重背包可行性】POJ-1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...

  3. poj1014 Dividing (多重背包)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:id=1014">http://poj.org/problem?id=1014 Descrip ...

  4. POJ1014:Dividing(多重背包)

    http://poj.org/problem?id=1014 Description Marsha and Bill own a collection of marbles. They want to ...

  5. [POJ1014]Dividing(二进制优化多重背包)

    #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int ...

  6. hdu1059&poj1014 Dividing (dp,多重背包的二分优化)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  7. poj分类解题报告索引

    图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...

  8. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  9. 【poj1014】 Dividing

    http://poj.org/problem?id=1014 (题目链接) 题意 给出有分别价值为1,2,3,4,5,6的6种物品,输入6个数字,表示相应价值的物品的数量,问一下能不能将物品分成两份, ...

  10. LeetCode算法题-Self Dividing Numbers(Java实现)

    这是悦乐书的第305次更新,第324篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是728).自分割数是一个可被其包含的每个数字整除的数字.例如,12 ...

随机推荐

  1. JS宣传页项目-综合实战

    按照国际惯例先放图 index.html <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  2. html颜色名颜色代码对照表

  3. node常用模块汇总

    node常用模块汇总: 点击插件名字,查看使用文档 npm常用模块汇总 node常用模块汇总 gulp常用插件汇总 mkdirp:在node.js中像mkdir -p一样递归创建目录及其子目录

  4. [Python机器学习]机器学习概述

    1.为何选择机器学习 在智能应用的早期,许多系统使用人为的if和else语句来处理数据,以主动拦截邮箱的垃圾邮件为例,可以创建一个关键词黑名单,所有包含这些关键词的邮件被标记为垃圾邮件,这是人为制定策 ...

  5. Disharmony Trees HDU - 3015 树状数组+离散化

    #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using ...

  6. vConsole 让你在手机上也能轻松调试网页

    有时候为了想在手机真机上对网页进行 Debug,可手机上没有 F12,用 Chrome DevTools 连接手机操作又太过复杂.VConsole 的出现,正好解决了这一痛点! (下列内容照搬一下官方 ...

  7. Spark学习之路 (二)Spark2.3 HA集群的分布式安装[转]

    下载Spark安装包 从官网下载 http://spark.apache.org/downloads.html 从微软的镜像站下载 http://mirrors.hust.edu.cn/apache/ ...

  8. java中拦截器与过滤器

    注:文摘自网络,仅供自己参考 1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之 ...

  9. 栈和队列----最大值减去最小值小于等于num的子数组的数量

    最大值减去最小值小于等于num的子数组的数量 给定数组arr和整数 num,共返回有多少个数组满足下列情况: max(arr[i..j])-min(arr[i..j])<=num.其中max(a ...

  10. usim卡介绍