题解-拉格朗日(bzoj3695变种)
Problem
在无穷大的水平面上有一个平面直角坐标系,\(N-1\)条垂直于\(x\)轴的直线将空间分为了\(N\)个区域
你被要求把\((0,0)\)处的箱子匀速推到\((x,y)\)
箱子受水平面的摩擦力与正压力正相关,所以在第\(i\)个区域的摩擦力可以表示为\(f_i\)
求把箱子推到目的地做的最小功是多少呢?(不考虑改变速度时的做功)
\(N\leq 100\)
Thoughts
这道题看题面是物理题,但一般来说这些题都是借着物理题的外表掩饰自己的数学本质
以为要从两块区域的简单情形入手,但我发现自己连两块区域都不会做;想到如果所有的\(f_i\)都相等的话,那么只要连一条直线即可,那么想法儿把\(f_i\)化进去,但发现\(\sqrt {x^2+y^2}\)的式子好像没法把\(f_i\)的系数化进去
转念一想,发现箱子肯定在\(f_i\)更大的地方移动得越少,而且在同一块区域内肯定是走直线,所以两块区域中的直线在交界的地方肯定有一个角度偏差,即箱子的整条移动路径是一条折线段
马上可以联想到光在不同介质交界处的折射现象
Physics
既然我们要利用折射计算精确值,那么我们就不能像初中那样仅仅掌握判断入射角和折射角大小关系的方法,我们需要定量计算!
惠更斯原理
惠更斯原理是指球形波面上的每一点(面源)都是一个次级球面波的子波源,子波的波速与频率等于初级波的波速和频率,此后每一时刻的子波波面的包络就是该时刻总的波动的波面。其核心思想是:介质中任一处的波动状态是由各处的波动决定的
看下面几幅图片基本就能理解
(图引自百度)
折射
有了这个原理,我们来证明一个定量的折射定理,如下图
光线在同一时间于\(A,B\)两点处放出子波源,在一个极短的时间\(\Delta t\)内,\(A\)放出的子波源到达\(C\)点,\(B\)放出的子波源到达\(D\),则有
\begin{matrix}
\sin i=\frac {\Delta tv_1}{AD}\\
\sin r=\frac {\Delta tv_2}{AD}\\
\end{matrix}
\right\}\Rightarrow \frac {\sin i}{\sin r}=\frac {v_1}{v_2}
\]
Solution
如何将上面的式子进行应用呢,由于并不是\(f_i\)越大答案越优,所以我们可以取\(v_i=\frac 1{f_i}\),则我们可以得到任意相邻两区间直线斜率的关系:
\]
但我们并不知道任何区间的斜率,所以我们可以设第一个区间的斜率为\(\theta_0\)(即从原点射出的第一条线段),并且考虑到这条折线在结束横坐标\(x\)的纵坐标\(y_0\)是关于\(\theta_0\)单调递增的,所以我们可以二分\(\theta_0\)来逼近最终我们的期望结束纵坐标\(y\),而我们要求答案的最小值,则我们只有当\(y_0\geq y\)时才能更新答案
……当我们开开心心打完代码,会发现连第二个样例都过不了,交上去只有\(20∽30\)分,问题出在哪了?
容易想到 调试发现 由于我们是以\(\sin \theta\)为途径转移,而途中我们的\(\sin \theta\)可能会出现大于\(1\)的情况,而这种情况的发生是并不是因为发生了全反射,而是我们设的初始值\(\theta_0\)不合法,我们要求\(\forall i\in [1,n],\sin \theta \in [-1,1]\),而\(\sin \theta =\sin \theta_0\frac {f_1}{f_i}\)
所以我们需要设定二分的上界\(\sin \theta_0\leq \frac {\min\{f_i\}}{f1}\),至此此题解决
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register
#define pi (3.14159265358979323846)
const int N=110;
const double eps=1e-8;
double x[N],f[N];
double ans=1e20,Y;
int n;
inline int calc(double theta){
double y=0.0,yy,res=0.0;
theta=sin(theta);
for(rg int i=1;i<=n;++i){
yy=x[i]*tan(asin(theta));
theta*=f[i]/f[i+1];
res+=sqrt(x[i]*x[i]+yy*yy)*f[i];
y+=yy;
}
if(y>Y)
ans=fmin(ans,res);
return y>Y;
}
int main(){
scanf("%d",&n);
double l=0.0,r=pi*0.5,m,mi=1e20;
for(rg int i=1;i<=n;++i){
scanf("%lf%lf",&x[i],&f[i]);
if(i^1)mi=fmin(mi,f[i]);
}
scanf("%lf",&Y);
r=min(r,asin(mi/f[1]));
while(l+eps<r){
m=(l+r)*0.5;
if(calc(m))r=m;
else l=m;
}printf("%.3lf\n",ans);
return 0;
}
题解-拉格朗日(bzoj3695变种)的更多相关文章
- BZOJ2876 [Noi2012]骑行川藏 【拉格朗日乘数法】
题目链接 BZOJ 题解 拉格朗日乘数法 拉格朗日乘数法用以求多元函数在约束下的极值 我们设多元函数\(f(x_1,x_2,x_3,\dots,x_n)\) 以及限制\(g(x_1,x_2,x_3,\ ...
- 【BZOJ】2876: [Noi2012]骑行川藏
题意 给出\(s_i, k_i, v_i', E\),满足\(\sum_{i=1}^{n} k_i s_i ( v_i - v_i' )^2 \le E, v_i > v_i'\),最小化$ \ ...
- BZOJ2287: 【POJ Challenge】消失之物
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 254 Solved: 140[Submit][S ...
- 题解 P4781 【【模板】拉格朗日插值】
题目 本蒟蒻看到一道数学题,就顺手切了.感觉单单对这一题而言,部分评论区的大佬过于复杂了 [分析] 先讲讲拉格朗日插值法: 对于给定的 \((n+1)\) 个点,我们可以确定唯一的一个 至多\(n\) ...
- 【LeetCode题解】二叉树的遍历
我准备开始一个新系列[LeetCode题解],用来记录刷LeetCode题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有 ...
- 【LeetCode题解】数组Array
1. 数组 直观地看,数组(Array)为一个二元组<index, value>的集合--对于每一个index,都有一个value与之对应.C语言中,以"连续的存储单元" ...
- 华南师大 2017 年 ACM 程序设计竞赛新生初赛题解
题解 被你们虐了千百遍的题目和 OJ 也很累的,也想要休息,所以你们别想了,行行好放过它们,我们来看题解吧... A. 诡异的计数法 Description cgy 太喜欢质数了以至于他计数也需要用质 ...
- bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)
题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ...
- 【CSA35G】【XSY3318】Counting Quests DP 拉格朗日反演 NTT
题目大意 zjt 是个神仙. 一天,zjt 正在和 yww 玩猜数游戏. zjt 先想一个 \([1,n]\) 之间的整数 \(x\),然后 yww 开始向他问问题. yww 每次给 zjt 一个区间 ...
随机推荐
- layui(五)——form组件常见用法总结
form 是我们非常看重的一块.layui中的form实现全自动的初始渲染,和基于事件驱动的接口书写方式.我整理了layui中form的配置.下边直接给一个栗子,后台采用.net MVC,除了razo ...
- 谈谈关于PHP连接数据库的两种方法(PDO&Mysqli)
前言:在我们之前学习sql语句的时候都是停留在黑窗口的,怎样才能让mysql与程序代码发生联系呢?此时PDO和Mysqli应运而生,为了解决这个问题 (一)开启其中(pdo或者mysqli)的php扩 ...
- CNPM
cnpm 代替 npm npm install -g cnpm --registry=https://registry.npm.taobao.org Reference 淘宝 NPM 镜像
- HDU 6425(羽毛球组合 **)
题意是说有四种同学,没有球拍没有球的( a ),只有球拍的( b ),只有球的( c ),既有球拍又有球的( d ):现在要去打羽毛球,每个人都可以选择去或者不去,问有多少种无法打羽毛球的情况. 无法 ...
- 转载--关于hdfs
原文章链接 你肯定听过Hadoop,对就是那头奔跑的小象. 图片描述 Hadoop作为大数据时代代表性的解决方案被大家所熟知,它主要包含两部分内容: HDFS分布式文件存储 MapReduce分布式计 ...
- idea上使用maven模块开发
使用maven模块开发: 使用Maven构建多模块项目 在平时的Javaweb项目开发中为了便于后期的维护,我们一般会进行分层开发,最常见的就是分为common(域模型层).dao(数据库访问层).s ...
- Vue.js入门系列教程(三)
序言
- shutdown函数
#include <sys/socket.h> int shutdown(int sockfd, int howto); 返回:若成功则为0,若出错则为- (1)该函数的行为依赖于howt ...
- nginx默认80端口被System占用,造成nginx启动报错的解决方案
今天启动window上的nginx总是报错 错误信息是bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socke ...
- UE4 编译笔记
UE4 的功能被分成了很多的模块,在API文档里每个类都有 Module 这个属性(值为模块名)每个模块使用其他模块要在Build.cs里导入,像vs里的引入库.在构建时 PublicDependen ...