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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端桌面通知(Desktop Notifications)API

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

msvcrtd.dll下载安装方法,解决msvcrtd.dll找不到的问题

在这篇文章中&#xff0c;我们将详细讨论msvcrtd.dll文件的下载安装方法&#xff0c;并分析出现找不到msvcrtd.dll的情况及解决方法。如果你遇到了与msvcrtd.dll相关的问题&#xff0c;本文将为你提供全面且详细的解决方案。 一.什么是msvcrtd.dll文件 首先&#xff0c;让我们…

JS中的String常用的实例方法

splice():分隔符 把字符串以分隔符的形式拆分为数组 const str pink,red;const arr str.split(,);console.log(arr);//Array[0,"pink";1:"red"]const str1 2022-4-8;const arr1 str1.split(-);console.log(arr1);//Array[0,"2022";1:"…

权重衰减(Weight Decay)

在深度学习中&#xff0c;权重衰减&#xff08;Weight Decay&#xff09;是一种常用的正则化技术&#xff0c;旨在减少模型的过拟合现象。权重衰减通过向损失函数添加一个正则化项&#xff0c;以惩罚模型中较大的权重值。 一、权重衰减 在深度学习中&#xff0c;模型的训练过程…

leetcode移除元素

移除元素 题目分析题解代码:c版本c版本 题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺…

六大场景36种数据分析模型及方法图示,数据分析师必备!

【关注微信公众号&#xff1a;跟强哥学SQL&#xff0c;回复“笔试”免费领取大厂SQL笔试题。】 我一直认为&#xff0c;实际工作中&#xff0c;精通数据分析工具仅仅只是数据思维训练的一部分&#xff0c;掌握丰富的数据分析方法和模型实际上更为重要。 基于科学的数据分析方法…

『PyTorch』张量和函数之gather()函数

文章目录 PyTorch中的选择函数gather()函数 参考文献 PyTorch中的选择函数 gather()函数 import torch a torch.arange(1, 16).reshape(5, 3) """ result: a [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12],[13, 14, 15]] """# 定义两个index…

Tomcat-指定启动jdk、修改使用的jdk版本

修改tomcat配置文件setclasspath.sh 配置文件首行增加以下代码&#xff0c;指定启动的jdk&#xff1a; export JAVA_HOME/opt/softwares/jdk1.8.0_211/ export JRE_HOME/opt/softwares/jdk1.8.0_211/jre

【Kafka】Kafka的重复消费和消息丢失问题

文章目录 前言一、重复消费1.1 重复消费出现的场景1.1.1 Consumer消费过程中&#xff0c;进程挂掉/异常退出1.1.2 消费者消费时间过长 1.2 重复消费解决方案1.2.1 针对于消费端挂掉等原因造成的重复消费问题1.2.2 针对于Consumer消费时间过长带来的重复消费问题 二、消息丢失2.…

【Qt5】QVersionNumber

2023年12月10日&#xff0c;周日上午 QVersionNumber 是 Qt 框架中用于表示版本号的类。它提供了一种方便的方式来处理和比较版本号&#xff0c;特别是在应用程序或库需要与特定版本的依赖项进行交互时。 以下是一个简单的示例&#xff0c;演示了如何使用 QVersionNumber&…

Spring-temp

IOC/DI实现步骤 1.配置元数据 2.实例化IOC 3.获取Bean 基于XML配置方式 管理组件 1.基于构造函数&#xff1a;有参、无参 2.基于静态工厂方法&#xff1a;有参、无参 依赖注入 1.构造函数 2.setter方法 Bean组件高级特性 1.作用域 2.生命周期 FactoryBean 基于注解 IOC Bean作…

Python如何匹配库的版本

目录 1. 匹配库的版本 2. Python中pip&#xff0c;库&#xff0c;编译环境的问题回答总结 2.1 虚拟环境 2.2 pip&#xff0c;安装库&#xff0c;版本 1. 匹配库的版本 &#xff08;别的库的版本冲突同理&#xff09; 在搭建pyansys环境的时候&#xff0c;安装grpcio-tools…

加权准确率WA,未加权平均召回率UAR和未加权UF1

加权准确率WA&#xff0c;未加权平均召回率UAR和未加权UF1 1.加权准确率WA&#xff0c;未加权平均召回率UAR和未加权UF12.参考链接 1.加权准确率WA&#xff0c;未加权平均召回率UAR和未加权UF1 from sklearn.metrics import classification_report from sklearn.metrics impor…

Python中的程序逻辑经典案例详解

我的博客 文章首发于公众号&#xff1a;小肖学数据分析 Python作为一种强大的编程语言&#xff0c;以其简洁明了的语法和强大的标准库&#xff0c;成为了理想的工具来构建这些解决方案。 本文将通过Python解析几个经典的编程问题。 经典案例 水仙花数 问题描述&#xff1a…

三勾商城新功能-电子面单发货

商家快递发货时可以选择在线下单,在线获取和打印电子面单。免去手写面单信息以及避免填写运单号填错,系统会自动填写对应发货商品的运单信息 快递100电子面单1、进入快递100&#xff0c;点击登录 2、登录成功后&#xff0c;点击“电子面单与云打印” 3、进入电子面单与云打印后…

Druid-spring-boot-starter源码阅读-其余组件自动装配

前面我们看完了整个DruidDataSource初始化流程&#xff0c;但是其实Druid除了最核心的数据源之外&#xff0c;还有其他需要自动配置的&#xff0c;细心的人可能看到了&#xff0c;就是利用Import注解导入的四个类。 DruidFilterConfiguration public class DruidFilterConfigu…

解决:TypeError: write() argument must be str, not tuple

解决&#xff1a;TypeError: write() argument must be str, not tuple 文章目录 解决&#xff1a;TypeError: write() argument must be str, not tuple背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在使用之前的代码时&#xff0c;报错&…

缓存的定义及重要知识点

文章目录 缓存的意义缓存的定义缓存原理缓存的基本思想缓存的优势缓存的代价 缓存的重要知识点 缓存的意义 在互联网高访问量的前提下&#xff0c;缓存的使用&#xff0c;是提升系统性能、改善用户体验的唯一解决之道。 缓存的定义 缓存最初的含义&#xff0c;是指用于加速 …

联邦边缘学习中的知识蒸馏综述

联邦边缘学习中的知识蒸馏综述 移动互联网的快速发展伴随着智能终端海量用户数据的产生。如何在保护数据隐私的前提下,利用它们训练出性能优异的机器学习模型,一直是业界关注的难点。为此,联邦学习应运而生,它允许在终端本地训练并协同边缘服务器进行模型聚合来实现分布式机器…

下午好~ 我的论文【yolo1~4】(第二期)

写在前面&#xff1a;本来是一期的&#xff0c;我看了太多内容了&#xff0c;于是分成三期发吧 TAT &#xff08;捂脸&#xff09; 文章目录 YOLO系列v1v2v3v4 YOLO系列 v1 You Only Look Once: Unified, Real-Time Object Detection 2015 ieee computer society 12.3 CCF-C…