题解-拉格朗日(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 一个区间 ...
随机推荐
- HDFS-JavaAPI
一.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- Jenkins自动化部署war项目
基于上一篇Jenkins安装环境,下面对自动打包部署做个备忘 1.安装:Publish over SSH 插件 2.安装完成后,进入下图配置 ↓↓↓ 3.翻到底下↓↓↓ 找到刚刚安装的Publish ...
- Hudson管理平台自动化部署war包
继上一篇:Hudson持续集成管理平台搭建 后,我们需要进行项目的自动化部署. 首先:我们先配置<系统管理>中的[系统设置] 然后返回到首页,点击项目名称进入项目内,点击设置: 翻到最底下 ...
- Spark设计理念与基本架构
1.基本概念 Spark中的一些概念: RDD(resillient distributed dataset):弹性分布式数据集. Partition:数据分区.即一个RDD的数据可以划分为多少个分区 ...
- [Android] Android Studio 使用config.gradle统一管理项目的依赖库
gradle支持自定义config.gradle,在GoogleSamples中提到我们必须使用关键字ext(对应ExtraPropertitesExtension的实例)来定义动态属性 如何实现: ...
- 配置tomcat限制指定IP地址访问后端应用
1. 场景后端存在N个tomcat实例,前端通过nginx反向代理和负载均衡. tomcat1 tomcatN | | | ...
- Spring 单例模式
恶汉模式:Ehan.java package com.cn.danli; /** * 饿汉式单例模式 */ public class Ehan { private static Ehan eh = n ...
- Android设置状态栏颜色
1.代码设置if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = this.getWindow ...
- Oracle数据库XXE注入漏洞(CVE-2014-6577)分析
在这篇文中,我们将共同分析一下Oracle数据库的XXE注入漏洞(CVE-2014-6577),Oracle公司1月20日发布了针对该漏洞的相关补丁. 有关XXE的相关知识,可以查看安全脉搏站内的另一 ...
- python函数后面有多个括号怎么理解?
一般而言,函数后面只有一个括号.如果看见括号后还有一个括号,说明第一个函数返回了一个函数,如果后面还有括号,说明前面那个也返回了一个函数.以此类推. 比如fun()() def fun(): prin ...