题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059

题意 : 按顺序读入一些列数,所对应的序列代表价值,数值代表个数(如a[5]=6 ,代表价值为五的钻石个 ), 通过计算判断这些钻石能否被平均分成二等分;

分析:已知正常多重背包复杂度为O((ΣN[i])V),这里(ΣN[i])<=120000,V<=60000;如果直接进行多重背包肯定超时。所以我们用二进制优化的多重背包。

这个复杂度为O(V*log((ΣN[i]))),优化了许多。。。至于原理背包九讲那里说得很清楚了。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 1<<30
#define N 100010
using namespace std;
int cnt[];
int dp[];
int main()
{
int a[],cas=;
while(scanf("%d",&a[])>)
{
int sum=a[];
for(int i=;i<=;i++)scanf("%d",&a[i]),sum+=a[i]*i;
if(sum==)break;
printf("Collection #%d:\n",cas++);
if(sum%)
{
puts("Can't be divided.\n");continue;
}
memset(dp,,sizeof(dp));
for(int i=;i<=a[];i++)dp[i]=;
dp[]=;
for(int i=;i<=;i++)
{
if(!a[i])continue;
int num=;
for(int j=;j<=a[i];j*=)
{
cnt[num++]=i*j;
a[i]-=j;
}
if(a[i]>)
{
cnt[num++]=a[i]*i;
}
for(int j=;j<num;j++)
{
for(int k=sum/;k>=cnt[j];k--)
{
dp[k]=dp[k]||dp[k-cnt[j]];
}
}
}
if(dp[sum/]!=)puts("Can be divided.");
else puts("Can't be divided.");
puts("");
}
}

还有种方法就是正常多重背包但是有技巧地剪枝,而且AC才78ms,前面二进制优化的多重背包要250ms

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 1<<30
#define N 100010
using namespace std;
int dp[];
int main()
{
int a[],cas=;
while(scanf("%d",&a[])>)
{
int sum=a[];
for(int i=;i<=;i++)scanf("%d",&a[i]),sum+=a[i]*i;
if(sum==)break;
printf("Collection #%d:\n",cas++);
if(sum%)
{
puts("Can't be divided.\n");continue;
}
memset(dp,-,sizeof(dp));
for(int i=;i<=a[];i++)dp[i]=;
dp[]=;
for(int i=;i<=;i++)
{
if(!a[i])continue;
for(int k=sum/;k>=;k--)
{
if(dp[k]==-)continue;
for(int j=;j<=a[i]&&i*j+k<=sum/;j++)
{
//这里剪枝最为关键,因为如果dp[i*j+k]=1后说明这个循环已经进行过一次了,没必要重复了
if(dp[i*j+k]!=-)break;
dp[i*j+k]=;
}
}
}
if(dp[sum/]!=-)puts("Can be divided.");
else puts("Can't be divided.");
puts("");
}
}

hdu1059(多重背包)的更多相关文章

  1. hdu1059 多重背包(转换为01背包二进制优化)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1059 之前写过一个多重背包二进制优化的博客,不懂请参考:http://www.cnblog ...

  2. hdu1059(多重背包优化)

    使用一种二进制的优化, 可以完美的解决这题,<背包九讲>中说的非常好 但是还有一种线性复杂的算法. 应该算是该题很巧妙的解法 ;i++) { ;l--) { ) continue; ;k& ...

  3. hdu1059 dp(多重背包二进制优化)

    hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听 ...

  4. hdu-1059(多重背包+二进制优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意:输入6个数,每个数ni代表价值为i的物品有ni个.求如果这些物品能均分给两个人,每个人获得 ...

  5. HDU1059 二进制拆分优化多重背包

    /*问你能不能将给出的资源平分成两半,那么我们就以一半为背包,运行多重背包模版 但是注意了,由于个数过大,直接运行会超时,所以要用二进制拆分每种的个数*/ #include<stdio.h> ...

  6. dp之多重背包hdu1059

    题意:价值为1,2,3,4,5,6. 分别有n[1],n[2],n[3],n[4],n[5],n[6]个.求能否找到满足价值刚好是所有的一半的方案. 思路:简单的多重背包,我建议多重背包都用二进制拆分 ...

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

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

  8. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  9. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

随机推荐

  1. 解 自己关于 C# Button的Click事件的疑惑

    先说说C#中事件的用法,从事件的用法中,我自己会产生一个疑惑 C#事件 class Program { static void Main(string[] args) { EventClass ec ...

  2. Cloudera Hadoop 4 实战课程(Hadoop 2.0、集群界面化管理、电商在线查询+日志离线分析)

    课程大纲及内容简介: 每节课约35分钟,共不下40讲 第一章(11讲) ·分布式和传统单机模式 ·Hadoop背景和工作原理 ·Mapreduce工作原理剖析 ·第二代MR--YARN原理剖析 ·Cl ...

  3. 1.0.3-学习Opencv与MFC混合编程之---打开本地摄像头

    源代码:http://download.csdn.net/detail/nuptboyzhb/3961643 版本1.0.3新增内容 打开摄像头 Ø 新建菜单项,Learning OpenCV——&g ...

  4. Apache 服务器

    1.介绍 Apache原来用于小型或试验性Internet网络,后来逐步扩展到各种系统中,对Linux的支持几乎完美.Apache可以支持SSL技术,支持多台虚拟主机.Apache是以进程为基础的结构 ...

  5. HBase数据存储格式

    好的数据结构,对于检索数据,插入数据的效率就会很高. 常见的数据结构 B+树 根节点和枝节点非常easy,分别记录每一个叶子节点的最小值,并用一个指针指向叶子节点.  叶子节点里每一个键值都指向真正的 ...

  6. ufldl学习笔记和编程作业:Feature Extraction Using Convolution,Pooling(卷积和汇集特征提取)

    ufldl学习笔记与编程作业:Feature Extraction Using Convolution,Pooling(卷积和池化抽取特征) ufldl出了新教程,感觉比之前的好,从基础讲起.系统清晰 ...

  7. 后台调用外部程序的完美实现(使用CreateDesktop建立隐藏桌面)

    最近在做的一个软件,其中有一部分功能需要调用其它的软件来完成,而那个软件只有可执行文件,根本没有源代码,幸好,我要做的事不难,只需要在我的程序启动后,将那个软件打开,在需要的时候,对其中的一个文本矿设 ...

  8. input在苹果浏览器下变成圆角的解决方案

    复制代码代码如下: .form-actions input{ ... -webkit-appearance: none; } 更新到iPhone一看,真爽,问题解决了.

  9. nodejs+socket.io即时聊天实例

    在这之前你应该先安装好 Node.js,安装过程不再讲解 首先在你的电脑上创建一个新目录,姑且命名为 chat,然后在该目录创建两个文件,分别是 app.js 和 index.html. app.js ...

  10. HDU4712-----Hamming Distance------超级大水题

    本文出自:http://blog.csdn.net/dr5459 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4712 题目意思: 海明距离:任意两个 ...