CH2401 送礼物

描述

作为惩罚,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

思路

这么小的数据。。。一般是搜索吧???这么大的W,用DP做肯定不成,而且也不资瓷离散化。。。。

直接搜?+剪枝?我已经剪不下去了。。。不过80分勉勉强强还可以~

代码(搜索+剪枝)

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 50 int N;
LL W, ans;
LL G[MAXN], f[MAXN];//f表示“后缀和” bool cmp( LL x, LL y ){ return x > y; } void DFS( int x, LL h ){//x表示当前搜的是第x件物品,h表示已经取到的总重量
while( x <= N && h + G[x] > W ) x++;//由于是降序排序,找到第一个还能继续搬的物品
if ( x > N ){ ans = max( ans, h ); return; }//没东西了(或者没有可以搬的了),当然得回溯 for ( ; x <= N; ++x ){
if ( h + f[x] <= W ){ ans = max( ans, h + f[x] ); return; }//剪枝~ 后面都能拿,当然要都拿来最优啦~ 这个剪枝可以看做是最优化剪枝
DFS( x + 1, h + G[x] );
}
} int main(){
scanf( "%lld%d", &W, &N );
for ( int i = 1; i <= N; ++i ) scanf( "%lld", &G[i] );
sort( G + 1, G + N + 1, cmp );//剪枝~ 降序排序再搜~
for ( int i = N; i >= 1; --i ) f[i] = f[i + 1] + G[i]; DFS( 1, 0 );
printf( "%lld\n", ans );
return 0;
}

相信大家都不会仅满足于80分~还有俩测试点呢。。。

我们用一种神奇的搜索方式——双向搜索!

也就是说,先找前半段,预处理出所有可以达到的总重量,存在一个数组F中,然后再搜索后半段,对于后半段已取的质量,在F中二分找出既满足条件,又最大的重量,加起来更新ans的值就可以了。这样复杂度就为O(\(2^{\frac n 2 }+2^{\frac n 2 } \times \log_2n\))基本可以满足要求。

代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 50 int N, M;
LL W, ans;
LL G[MAXN];
LL F[20000000], tot; bool cmp( LL x, LL y ){ return x > y; } void DFS_1( int x, LL h ){//第一次搜索,注意所有能得到的重量都要记录,所以不必剪枝 还有注意0也要记录
F[++tot] = h;
while( x <= M && h + G[x] > W ) x++;
for ( ; x <= M; ++x ) DFS_1( x + 1, h + G[x] );
} int EF( LL x ){//手打二分~
int l(1), r(tot), mid, ans(1);
while( l <= r ){
mid = ( l + r ) >> 1;
if ( F[mid] + x <= W ) l = mid + 1, ans = mid;
else r = mid - 1;
}
return ans;
} void DFS_2( int x, LL h ){
ans = max( ans, h + F[EF(h)] );
while( x <= N && h + G[x] > W ) x++;
for ( ; x <= N; ++x ) DFS_2( x + 1, h + G[x] );
} int main(){
scanf( "%lld%d", &W, &N ); M = ( N >> 1 ) + 2;//lyd大佬说前半段1~N/2+2最快~蒟蒻当然照做
for ( int i = 1; i <= N; ++i ) scanf( "%lld", &G[i] );
sort( G + 1, G + N + 1, cmp );//照样排序 DFS_1( 1, 0 );
sort( F + 1, F + tot + 1 ); tot = unique( F + 1, F + tot + 1 ) - F - 1;//排序&去重
DFS_2( M + 1, 0 );
printf( "%lld\n", ans );
return 0;
}

搜索真是博大精深~

「CH2401」送礼物 解题报告的更多相关文章

  1. 「JSOI2015」送礼物

    「JSOI2015」送礼物 传送门 看到这题首先想到分数规划. 我们发现对于当前区间,如果它的最大值和最小值不是分居区间的两个端点的话,那么我们显然可以把两端多出去的部分舍掉,因为,在区间最大值最小值 ...

  2. 「FJOI2016」神秘数 解题报告

    「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...

  3. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  4. 「SCOI2016」背单词 解题报告

    「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...

  5. 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...

  6. 「SCOI2015」国旗计划 解题报告

    「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...

  7. 「JLOI2015」骗我呢 解题报告?

    「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...

  8. 「JLOI2015」城池攻占 解题报告

    「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...

  9. 「JLOI2015」管道连接 解题报告

    「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...

随机推荐

  1. phpstorm2017破解版 2017.3.4 官网中文版

    phpstorm2017破解版是一款强大的PHP编程工具,新云软件园提供phpstorm激活下载,最新版PhpStorm 2017正式版改进了PHP 7支持,改进代码完成功能,PhpStorm 是最好 ...

  2. Android的headerView和emptyView共存问题

    今天做项目的时候,准备优化下ListView相关的东西,于是乎,需要做一个当列表无数据时,空的提醒页面.这个自然想到的是ListView的setEmptyView()方法,于是顺手就写了,可是,当我为 ...

  3. 微信小程序封装自定义弹窗

    最近在做小程序的登录,需要同时获取用户手机号和头像昵称等信息,但是小程序又不支持单个接口同时获取两种数据,因此想到自定义一个弹窗,通过弹窗按钮触发获取手机号事件.记录一下. 具体代码如下: 业务代码中 ...

  4. 全文检索 java Lucene

    索引文件:[D:\luceneDemo\data\TXT小说\陛下是妻迷.txt] 大小:[1185.0 KB] 索引文件:[D:\luceneDemo\data\TXT小说\随身空间重生在七十年代. ...

  5. H3C 快速以太网和千兆以太网

  6. hdu 1217 Arbitrage(佛洛依德)

    Arbitrage Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  7. MVC插件式开发平台

    ---恢复内容开始--- 经过DyOS.BraveOS1.0再到BraveOS2.0,系统现在已经开发了下载. 我们的目标是,网页版操作系统,可以在线安装更新软件,并提供二次开发平台,提供基础的逻辑和 ...

  8. PHP两个变量值互换(不用第三变量)

    <?php /**  * 双方变量为数字或者字符串时  * 使用list()和array()方法可以达到交换变量值得目的  */ $a = "This is A"; // a ...

  9. git把某个文件去除版本控制

    谢谢@jessicway 同学的提醒.我之前没考虑只需要删除服务器上已提交的文件,但是本地不想删除的情况. 我们先看看 git rm 命令的说明 可以看到其实加上 --cached 参数就可以实现只去 ...

  10. Pandas库之DataFrame

    Pandas库之DataFrame 1 简介 DataFrame是Python中Pandas库中的一种数据结构,它类似excel,是一种二维表. 或许说它可能有点像matlab的矩阵,但是matlab ...