acwing-171. 送礼物(双向dfs+打标+二分)

acwing-171. 送礼物(双向dfs+打标+二分)达达帮翰翰给女生送礼物,翰翰一共准备了 N 个礼物,其中第 i 个礼物的重量是 G[i]。达达的力气很大,他一次可以搬动重量之和不超过 W 的任意多个物品。达达希望一次搬掉尽量重的一些物品,请你告诉达达在他的力气范围内一次性能搬动的最大重量是多少。输入格式第一行两个整数,分别代表 W 和 N。以后 N 行,每行一个正整数表示 G[i]。输出格式仅一个整数,表示达达在他的力气范围内一次性能搬动的最大重量。数据范围1≤N≤46,1≤W,G[i]≤231−1输入样例:20 5754

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

达达帮翰翰给女生送礼物,翰翰一共准备了 N 个礼物,其中第 i 个礼物的重量是 G[i]。

达达的力气很大,他一次可以搬动重量之和不超过 W 的任意多个物品。

达达希望一次搬掉尽量重的一些物品,请你告诉达达在他的力气范围内一次性能搬动的最大重量是多少。

输入格式
第一行两个整数,分别代表 W 和 N。

以后 N 行,每行一个正整数表示 G[i]。

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

数据范围
1≤N≤46,
1≤W,G[i]≤231−1

输入样例:
20 5
7
5
4
18
1
输出样例:
19

题解
由于N= 46,指数级别的时间复杂度不能超过25,所以考虑用双向dfs,可以头一次生成的序列打表记录下sum,然后第二次的时候直接二分查找

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 46;
const int K = 1 << 25;
ll a[N];
ll weight[K],cnt;
ll sum = 0;
ll res = 0;
ll w;
void dfs(int u,ll lsum){ 
   
    if(sum > w)return;
    if(u == lsum){ 
   
        weight[cnt ++] = sum;
        return;
    }
    if(u < lsum){ 
   
        sum += a[u];
        dfs(u + 1,lsum);
        sum -= a[u];
        dfs(u + 1,lsum);
    }
}
void dfs2(int u,ll lsum){ 
   
    if(u == lsum - 1 && sum <= w){ 
   
        int l = 0,r = cnt - 1;
        int t = w - sum;
        while(l < r){ 
   
            int mid = (l + r + 1) >> 1;
            if(weight[mid] <= t){ 
   
                l = mid;
            }
            else r = mid - 1;
        }
        res = max(res,weight[l] + sum);
        return;
    }
    else if(u >= lsum){ 
   
        sum += a[u];
        dfs2(u - 1,lsum);
        sum -= a[u];
        dfs2(u - 1,lsum);
    }
}
int main(){ 
   
    int n;
    cin>>w>>n;
    for(int i = 0;i < n;i ++)cin>>a[i];
    int lsum = max(n / 2 - 2, 0);
    dfs(0,lsum);
    sort(weight,weight + cnt);
    sum = 0;
    dfs2(n - 1,lsum);
    cout<<res<<endl;
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/168656.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2021前端面试经常被问到的题(附答案)

    2021前端面试经常被问到的题(附答案)一、html二、css1.50道CSS基础面试题(附答案)50道CSS基础面试题(附答案)2.如何居中div?CSS水平居中+垂直居中+水平/垂直居中的方法总结3.CSS3新特性深入了解CSS3新特性4.清除浮动清除浮动的四种方式及其原理理解5.media媒体查询深入浅出篇—media媒体查询-响应式开发必备6.讲一讲Flex布局,以及常用的属性?一…

    2022年8月29日
    4
  • centos7如何更改ip地址

    1.进入网络设置文件里面命令如下:这里最好是使用root用户,然后使用ls命令找到网络的配置文件。我这里的配置文件是ifcfg-ens33.然后使用vi命令进入文件进行编辑网络的ip地址等信息。然后按键盘i进入编辑模式,更改ip地址等信息。然后按esc键退出编辑模式,然后输入:wq!保存。2.使用servicenetworkrestart命令,重启网络服务。3.ping百…

    2022年4月7日
    136
  • vs Code 运行一个本地WEB服务器

    vs Code 运行一个本地WEB服务器vs Code 运行一个本地WEB服务器

    2022年4月23日
    96
  • TCP三次握手详解及释放连接过程[通俗易懂]

    TCP三次握手详解及释放连接过程[通俗易懂]TCP在传输之前会进行三次沟通,一般称为“三次握手”,传完数据断开的时候要进行四次沟通,一般称为“四次挥手”。两个序号和三个标志位:  (1)序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。  (2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。  (3)标志位:共6个,即URG、AC…

    2022年6月13日
    36
  • 忆贵州三年的教书编程岁月:不弛于空想,不骛于虚声「建议收藏」

    忆贵州三年的教书编程岁月:不弛于空想,不骛于虚声「建议收藏」回首,2016年7月他离开北京回到了家乡贵州,成为了贵州财经大学的一名青年教师。转眼,2019年7月他迎来了人生的第三张通知书,即将辗转第三个城市,开始新的征途。教书三年,讲台前的每一次分享都值得回味,学生的每一句“老师好”,每一个问候和祝福,都留下了深刻的印象。

    2022年10月7日
    3
  • 使用javascript实现对于chineseocr的API调用「建议收藏」

    ChineseOCR在线API网页地址界面提供多种接口调用方式,比如在线调用、Javascriptapi调用、curlapi调用和pythonapi调用四种方式,本次使用javascriptapi调用的方式进行OCR识别在线Javascript工具在线工具网页链接在线Base64转化工具在线工具网页链接代码修改新增一个变量fill_with_base64_image接收图片的base64编码的字符串 将input内的<fill_with_base6.

    2022年4月6日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号