2020 ICPC·小米邀请赛 决赛 J. Rikka with Book(状压dp)

题目

登录—专业IT笔试面试备考平台_牛客网

n(n<=20)本书,放在桌子上,

第i本书的可以看成是li(li<=1e3)*1*1的物体,其中长为li,宽为1,高为1,

质量均匀分布,且为wi(wi<=1e3)

求n本书摞在一起,使得任意一本书都不掉下桌子时,书能伸出桌沿的长度的最大值是多少

思路来源

官方题解&申老师

题解

放的话肯定是从上往下放,这样已经放上去的可以看成是一个物体,

并且当b物品摞在a物品之上时,一定是把b物品的重心放到a物品的边沿上,

好比把a物品当成桌子,一定是放到桌沿上,

再将a和b看成同一个物品时,一定是放到下一个物品的边沿上,

一旦一个物体的质量和重心的位置确定了,这个物品的其他属性就无关紧要了,从而无后效性

所以状压每次往下垫的书是哪一本,确定放的顺序,关注的是伸出去的最大值

往下垫的书的重心位于l/2处,质量为a;

上面的书看成一体时,重心位于边沿,质量为b

那么新的重心,根据杠杆原理,位于距边沿a/(a+b)的位置,记add=a/(a+b)

记原来的伸出去的最大值为x,则新的最大值为x+add,

此外,可以旋转一下整个物体,使整个物体的重心仍落在边沿上不落下去,

但是伸出边沿的是往下垫的书的另外半边,也就是l-add这半边,二者取max即可

所以,如果最优解是第i本书伸的最远,最上面的书是1,最下面的书是n,

一定是对于j∈[1,i-1]来说,把[1,j]看成一体时,[1,j]的重心压在j+1的左边沿,

对于j∈[i+1,n]来说,将[1,j-1]看成一体时,[1,j-1]的重心压在j的右边沿

每次枚举的时候,旋转or不旋转二选一都试一下,显然可以覆盖这种情况

代码1

维护的是长度l、到左边沿的距离p、整体的质量w

// Problem: Rikka with Book
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/9328/J?&headNav=acm
// Memory Limit: 1048576 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define scll(a) scanf("%lld",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N=20,M=(1<<20)+5;
int n;
db dp[M];
int lb(int x){return x&(-x);
}
struct node{db l,p;//长度 离左侧距离int w;//质量node(){l=0;p=1e7;w=0;}db dis(){return l-p;}void show(int i=-1){printf("i:%d l:%lf p:%lf w:%d\n",i,l,p,w);}
}e[M];
//b放在a上
bool operator>(node a,node b){return a.dis()>b.dis();
}
node mer(node a,node b){db x=a.l-a.p;node c;db B=a.w*x/(a.w+b.w);if(b.p>a.l){//b更左c.l=b.l;c.p=b.p-B;//b.l-b.p+B}else{//a更左c.l=a.l+b.l-b.p;c.p=a.l-B;//b.l-b.p+B}c.w=a.w+b.w;if(c.p>c.l-c.p)c.p=c.l-c.p;//puts("");//a.show();b.show();c.show();//puts("");return c;
}
void sol(){sci(n);rep(i,0,n-1){int x=1<<i;scanf("%lf",&e[x].l);e[x].p=e[x].l/2.0;}rep(i,0,n-1){int x=1<<i;scanf("%d",&e[x].w);}int up=(1<<n)-1;rep(i,1,up){if(lb(i)==i)continue;//printf("i:%d\n",i);rep(j,0,n-1){if(!(i>>j&1))continue;int v=1<<j,oth=i^v;node w=mer(e[v],e[oth]);//只枚举最底下那个是什么if(w>e[i])e[i]=w;//e[oth].p=e[oth].l-e[oth].p;//w=mer(e[v],e[oth]);//if(w>e[i])e[i]=w;//w.show();}//if(e[i].p>e[i].l-e[i].p)e[i].p=e[i].l-e[i].p;//b[1].p=b[1].l-b[1].p;//e[i].show(i);}printf("%.10lf\n",e[up].dis());
}
int main(){sol();return 0;
}

代码2(三个顶俩代码)

发现无需维护长度l和距一端的位置p,只维护右半边伸出去的最大值即可

每次尝试一下翻或不翻

#include <bits/stdc++.h>using namespace std;
int n,l[30],w[30],x[1100000];
double f[1100000];int main()
{int i,j;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&l[i]);for(i=0;i<n;i++)scanf("%d",&w[i]);for(i=1;i<(1<<n);i++){for(j=0;j<n;j++)if(i&(1<<j))break;x[i]=x[i-(1<<j)]+w[j];}for(i=1;i<(1<<n);i++){for(j=0;j<n;j++)if(i&(1<<j))f[i]=max(f[i],max(f[i^(1<<j)]+double(0.5*w[j]*l[j])/x[i],l[j]-double(0.5*w[j]*l[j])/x[i]));}printf("%.12lf\n",f[(1<<n)-1]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/227862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于linux系统的Tomcat+Mysql+Jdk环境搭建(二)jdk1.8 linux 上传到MobaXterm 工具的已有session里

【JDK安装】 1.首先下载一个JDK版本 官网地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下载1.8版本&#xff0c;用红框标注出来了&#xff1a; 也许有的同学看到没有1.8版本&#xff0c;你可以随便下载一个linux的…

平均数 C语言xdoj66

问题描述 计算n个整数&#xff08;x1,x2,x3...&#xff09;的平均数&#xff0c;结果保留两位小数。 输入说明 第一行为整数n&#xff08;1 < n <100&#xff09;&#xff0c;接下来是n个整数(0 < x1,x2,x3....< 2^31 - 1)。 输出说明 输出这n个整数的…

电商平台的易聊集成:无代码开发,API连接,CRM支持

连接电商与客服&#xff1a;易聊的创新解决方案 在迅速变化的电子商务市场中&#xff0c;企业要想保持竞争力&#xff0c;就必须拥有高效灵活的客服体系。易聊&#xff0c;一家领先的AISaaS服务商&#xff0c;正是基于这一需求&#xff0c;推出了一系列创新产品。它们通过智能…

C/C++ STL提供的关联式容器之map

map 由红黑树实现&#xff0c;其元素都是 “键值/实值” 所形成的一个对组&#xff08;key/value pairs)。 map 主要用于资料一对一映射的情况&#xff0c;map 内部自建一颗红黑树&#xff0c;这颗树具有对数据自动排序的功能&#xff0c;所以在 map 内部所有的数据都是有序的…

Vue2-动态组件案例

1.component介绍 说明&#xff1a; Type: string | ComponentDefinition | ComponentConstructor Explanation: String: 如果你传递一个字符串给 is&#xff0c;它会被视为组件的名称&#xff0c;用于动态地渲染不同类型的组件。这是一个在运行时动态切换组件类型的常见用例。…

【C++】 C++11 新特性探索:decltype 和 auto

▒ 目录 ▒ &#x1f6eb; 问题描述环境 1️⃣ decltype推导变量类型推导函数返回类型 2️⃣ auto自动推导变量类型迭代器和范围循环 3️⃣ decltype 和 auto 同时使用&#x1f6ec; 结论&#x1f4d6; 参考资料 &#x1f6eb; 问题 描述 C11 引入了一些强大的新特性&#xff…

高通平台开发系列讲解(USB篇)Composite USB gadget framework

文章目录 一、Gadget framework二、Composite driver and gadget driver interaction沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要图解高通平台PCIe EP软件架构 一、Gadget framework Composite USB gadget framework 架构如下所示: The composite fram…

什么是容器安全技术

容器可以让开发者将应用与库和其他依赖项打包&#xff0c;提供独立环境来运行其软件服务。将程序和程序运行所依赖的环境&#xff0c;数据库&#xff0c;配置文件都打包好&#xff0c;让其他人打开就可以使用。说起来容器也是一种虚拟化技术&#xff0c;虚拟的是操作系统。容器…

人工智能数据集可视化统计分析工具:快速了解你的数据集

人工智能数据集可视化统计分析工具&#xff1a;快速了解你的数据集 简介特征示例报告安装用法 简介 Lightly Insights&#xff1a;可以轻松获取关于机器学习数据集基本洞察的工具&#xff0c;可以可视化图像数据集的基本统计信息&#xff0c;仅需提供一个包含图像和对象检测标…

C++ Qt开发:标准Dialog对话框组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍标准对话框QInputDialog、QFileDialog 这两种…

腾讯云Linux云服务器禁Ping设置

腾讯云Linux服务器默认是允许ping包的&#xff0c;但是在一些情况下为了安全考虑起见&#xff0c;我们都会把服务器设置为禁ping的模式。 1、首先检查Linux服务器当前是否禁ping 执行命令&#xff1a; cat /proc/sys/net/ipv4/icmp_echo_ignore_all 备注&#xff1a; 0----代…

Next.js加载异步组件 骨架屏

Next.js 中有两种处理页面加载的方式&#xff0c;一种是 Loading UI 一种是 Streaming。接下来我将介绍这两种的区别&#xff0c;以及实际的业务场景。 当我们进入某个页面时&#xff0c;需要获取页面数据&#xff0c;可能是从数据库读取也有可能是 API 服务&#xff0c;总之这…

【人工智能革命】:AIGC时代的到来 | 探索AI生成内容的未来

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. AIGC 技术的概述和发展趋势1.1 AIGC 技术的概述1.2 AIGC 技术的发展趋势 二. AIGC 与元宇…

【C语言(十)】

字符函数和字符串函数 一、字符分类函数 C语言中有⼀系列的函数是专门做字符分类的&#xff0c;也就是⼀个字符是属于什么类型的字符的。这些函数的使用都需要包含⼀个头文件是 ctype.h 这些函数的使用方法非常类似&#xff0c;我们就讲解⼀个函数的事情&#xff0c;其他的非…

华为OD机试真题-多段线数据压缩-2023年OD统一考试(C卷)

题目描述: 下图中,每个方块代表一个像素,每个像素用其行号和列号表示。 为简化处理,多段线的走向只能是水平、竖直、斜向45度。 上图中的多段线可以用下面的坐标串表示:(2, 8), (3, 7), (3, 6), (3, 5), (4, 4), (5, 3), (6, 2), (7, 3), (8, 4), (7, 5)。 但可以发现,这…

springboot整合webflux访问openai接口报错

报错信息: org.springframework.web.reactive.function.client.WebClientRequestException: 远程主机强迫关闭了一个现有的连接。; nested exception is java.io.IOException: 远程主机强迫关闭了一个现有的连接。at org.springframework.web.reactive.function.client.Excha…

栈和队列的实现(Java篇)

文章目录 一、栈的概念二、栈的实现2.1压栈(push)2.2出栈(pop)2.3获取栈顶元素(peek)2.4判断栈是否为空(isEmpty)栈的实现测试 三、队列的概念四、队列的实现4.1入队(offer)4.2出队(poll)4.3判断队列是否为空4.4获取对头元素队列的实现测试 五、循环队列5.1入队5.2出队5.3获取队…

MAMOS蓝图: 打造自己的质量工程

针对团队中存在的问题&#xff0c;构造MAMOS蓝图&#xff0c;从而以系统化的方式识别并解决问题。本文将针对减少等待时间这一问题举例说明MAMOS蓝图的组成和使用方式。原文: MAMOS Blueprint: Build your own for Quality at Speed 很难完全摆脱等待时间。 我认为没有必要争论…

vue脚手架安装及使用

准备工作 安装node安装cnpm cnpm是npm的“廉价平替” 提高安装速度 npm install -g cnpm --registryhttps://registry.npm.taobao.org 安装脚手架 安装Vue脚手架 cnpm install -g vue/cli 用vue脚手架创建vue项目 找好创建项目的位置 创建项目 vue create test (test为项…

用代码写uml并在线生成uml图

可以用PlantUml写uml,并在线生成uml图。 startuml start:登录系统; if (用户名和密码正确?) then (yes):进入系统首页;:展示主菜单; else (no):显示登录错误;stop endif:选择模块; partition "课程信息" {:查看课程列表;:查看课程详情; } partition "课程签到…