题目链接:传送门

描述

作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了。某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_-b),他一次可以搬动重量和在w(w<=2^31-1)以下的任意多个物品。GY希望一次搬掉尽量重的一些物品,请你告诉他在他的力气范围内一次性能搬动的最大重量是多少。

输入格式

第一行两个整数,分别代表W和N。
以后N行,每行一个正整数表示G[i],G[i]<= 2^31-1。

输出格式

仅一个整数,表示GY在他的力气范围内一次性能搬动的最大重量。

样例输入

20 5
7
5
4
18
1

样例输出

19

数据范围与约定

    • 对于20%的数据 N<=26
      对于40%的数据 W<=2^26
      对于100%的数据 N<=45 W<=2^31-1

题解:

如果直接暴搜,时间复杂度 $O(2^N)$ 原地起爆,可以使用折半DFS。

礼物分成两半,前一半 $O(2^{N/2})$ 的暴搜每个礼物选不选,然后把每种方案的重量之和存到数组 $S$ 里,并且排序、去重,以备后用。

再对后一半礼物进行 $O(2^{N/2})$ 暴搜,每种方案得到了重量后,去前面 $S$ 里二分找两个重量和加起来最大,且不超过 $W$ 的那个 $S[i]$。

优化后的时间复杂度是 $O(2^{N/2} \cdot \log 2^{N/2}) = O(N \cdot \sqrt{2}^N)$。

原本想用状压,发现应该是被卡了,因为状态转成重量还要凭空再多 $O(N)$ 的复杂度,比较尴尬……以后码代码前得记得先算算复杂度……别拿个假算法死怼半天……

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=; int n,x;
ll w,g[maxn]; int tot;
ll S[<<(maxn>>)]; void dfs(int p,ll sum)
{
if(sum>w) return;
if(p>x)
{
S[++tot]=sum;
return;
}
dfs(p+,sum);
dfs(p+,sum+g[p]);
} ll ans;
ll srch(ll x)
{
int l=, r=tot;
while(l<r)
{
int mid=(l+r+)>>;
if(S[mid]<=x) l=mid;
else r=mid-;
}
return S[l];
}
void dfs2(int p,ll sum)
{
if(sum>w) return;
if(p>n)
{
ans=max(ans,sum+srch(w-sum));
return;
}
dfs2(p+,sum);
dfs2(p+,sum+g[p]);
} int main()
{
cin>>w>>n, x=(n+)/;
for(int i=;i<=n;i++) scanf("%d",&g[i]);
sort(g+,g+n+,greater<int>()); tot=;
dfs(,0LL);
sort(S+,S+tot+);
tot=unique(S+,S+tot+)-(S+); ans=;
dfs2(x+,0LL);
cout<<ans<<endl;
}

CH 2401 - 送礼 - [折半DFS+二分]的更多相关文章

  1. CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。

    1514: Packs Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 61  Solved: 4[Submit][Status][Web Board] ...

  2. uva 10004 Bicoloring(dfs二分染色,和hdu 4751代码差不多)

    Description In the ``Four Color Map Theorem" was proven with the assistance of a computer. This ...

  3. 【转】Java实现折半查找(二分查找)的递归和非递归算法

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://wintys.blog.51cto.com/425414/94051 Java二分 ...

  4. Java实现 LeetCode 655 输出二叉树(DFS+二分)

    655. 输出二叉树 在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则: 行数 m 应当等于给定二叉树的高度. 列数 n 应当总是奇数. 根节点的值(以字符串格式给出)应当放在可放置的第一 ...

  5. CH Round #72树洞[二分答案 DFS&&BFS]

    树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...

  6. Codeforces H. Prime Gift(折半枚举二分)

    题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...

  7. poj3977(折半枚举+二分查找)

    题目链接:https://vjudge.net/problem/POJ-3977 题意:给一个大小<=35的集合,找一个非空子集合,使得子集合元素和的绝对值最小,如果有多个这样的集合,找元素个数 ...

  8. 10324 Global Warming dfs + 二分

    时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description Global warming is a big prob ...

  9. hdu 5188 dfs+二分

    get了很多新技能 当时想到了用dfs,但是排序用的是限制时间排序,一直没搞出来. 正解: 二分用时,dfs判断,为了顺利进行做题,需要按照做题开始时间排序 还可以用dp 题意: 作为史上最强的刷子之 ...

随机推荐

  1. sql 有条件计数

    select InstitutionID=LEFT(InstitutionID,9), Irregularities_Type=sum(CASE WHEN Irregularities_Type> ...

  2. 【C++】C++中的引用与指针

    想必大家对C++中的指针都有所了解,但是什么是引用呢?C++11标准引入了“引用”的新功能. 引用 引用(reference):给对象起了另外一个名字,引用类型引用(refers to)另外一种类型, ...

  3. .NET领域最为流行的IOC框架之一Autofac WebAPI2使用Autofac实现IOC属性注入完美解决方案 AutoFac容器初步

    .NET领域最为流行的IOC框架之一Autofac   一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程 ...

  4. MySQL 4 种隔离级别的区别

    ## 测试环境 mysql> select version(); +------------+ | version() | +------------+ -log | +------------ ...

  5. k8s namespace/volume

    https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/ 只挑个人感觉使用较多/比较重要的点来说 ...

  6. Linux下C语言执行shell命令

    有时候在代码中需要使用到shell命令的情况,下面就介绍一下怎么在C语言中调用shell命令: 这里使用popen来实现,关于popen的介绍,查看 http://man7.org/linux/man ...

  7. python class和class(object)用法区别

    # -*- coding: utf-8 -*- # 经典类或者旧试类 class A: pass a = A() # 新式类 class B(object): pass b = B() # pytho ...

  8. Zookeeper —— 初识

    什么是 Zookeeper Zookeeper 是一个开放源代码的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现: Zookeeper 是典型的分布式数据一致性的解决方案,分布 ...

  9. caffe网络结构可视化在线工具

    http://ethereon.github.io/netscope/#/editor shift+enter

  10. idea设置条件断点

    只有在指定的条件下才触发断点,在idea中如何设置呢? 方法: 按Ctrl+Shift+F8弹出View Breakpoints 在Condition设置触发条件 结果: 源码 https://git ...