hdu5616 (01背包或者折半枚举)

原创 2018年04月17日 16:00:05

题意:n个砝码,给你若干个重物,问你是否能称出来。

题解:

n只有20所,直接枚举有三种状态,放左边,放右边,不放。共有3^20次方情况。

如果枚举一半,找另一半,找另一半共有2*(3^10)次方复杂度,方法可行。

还有一种折半方法,把20个物品重量取相反数变为40个物品,然后对于这40个物品的取放便包含了所有情况。直接枚举复杂度2^40,这题的重量很小,重复量很多,其实暴力枚举可以水过去。而另一种方法当然也是折半枚举,复杂度2*(2^20)。

最好理解的当然是01背包啦,这题物品重量不超过2000,超过2000肯定无解。我们直接对20个物品做个01背包,然后反过来对他们的相反数做个01背包就行了。注意加法背包和减法背包第二层循环方向是不同的。下面给出01背包代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

int dp[4005];
int a[30];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)cin>>a[i];
		dp[0]=1;
		
		
		for(int i=0;i<n;i++)
		for(int j=2000;j>=a[i];j--)
		dp[j]|=dp[j-a[i]];
		
		for(int i=0;i<n;i++)
		for(int j=0;j<=2000;j++)
		dp[j]|=dp[j+a[i]];
		
		int m;cin>>m;
		while(m--)
		{
			int x;cin>>x;
			if(x>2000)printf("NO\n");
			else if(dp[x]) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37632935/article/details/79976002

hdu5616Jam's balance(01背包或者折半搜素)(BestCoder Round #70 )

Jam's balance  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe...
  • acm_fighting
  • acm_fighting
  • 2016-02-02 11:02:34
  • 428

hdu5616

#include #include const int maxm=2001; const int mid=2005; int a[21]; int dp[maxm+10];int main() { ...
  • mymilkbottles
  • mymilkbottles
  • 2016-02-01 13:52:46
  • 315

hdu5616(理解01背包很好的题目)

这题一看到不就是01背包吗?直觉想到对不对!!!有木有!!!然而,01背包我们都是正的扫一遍,这里需要反的再扫一遍,而且背包里面不一定非要存储背的物体的重量,还可以是记录这个背包有没有用过哈~~~ ...
  • u014135021
  • u014135021
  • 2016-03-29 21:14:50
  • 537

hdu 3017 Treasure Division 折半枚举 + 双指针

运气不错排了第二。内存比他们大了好多。不知道他们是什么方法。 把n个coin分成两半,在两半里分别枚举所有情况,第一半取了i枚硬币则把价值存入s1[i],第二半取了i枚硬币则把价值存入s2[...
  • Techmonster
  • Techmonster
  • 2016-05-18 19:57:04
  • 462

折半枚举

折半枚举不是一般的双向搜索,当问题的规模较大,无法枚举所有元素的组合,但能够枚举一半元素的组合,此时将问题拆成两半后分别枚举,再合并它们的结果这一方法往往非常有效。 POJ 2785: 给...
  • rosepicker
  • rosepicker
  • 2017-04-27 15:03:53
  • 309

【折半枚举】

目录折半枚举 题1 折半枚举折半枚举是一种很好用的枚举方法,比如有时集合过大无法全部搜索,但刚好只需要他们的和或其他可以处理出的东西,就可以一半一半搜题14 Values whose Sum is 0...
  • qq_37636528
  • qq_37636528
  • 2017-03-15 21:26:45
  • 350

NOIP复赛复习(十七)尺取法与折半枚举

一、尺取法  尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。之所以需要掌握...
  • dqcsm1964
  • dqcsm1964
  • 2017-11-06 13:57:06
  • 86

超大背包问题 折半枚举法

#include    #include    #include    #include    using namespace std;   typedef long long ll;   ...
  • Little_boy_z
  • Little_boy_z
  • 2017-12-09 16:52:24
  • 60

密码锁 01背包

  • 2017年11月09日 21:38
  • 45KB
  • 下载

Codeforces 525E Anya and Cubes【折半枚举法+剪枝Dfs】好题~

E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes ...
  • mengxiang000000
  • mengxiang000000
  • 2016-11-10 13:08:45
  • 279
收藏助手
不良信息举报
您举报文章:hdu5616 (01背包或者折半枚举)
举报原因:
原因补充:

(最多只允许输入30个字)