什么毒瘤...

解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可。

n = 2的,猜测可以三分。于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间。注意剩余能量不足跑完第二段路的时候,返回INF。

正解是啥拉格朗日乘子法,完全搞不倒...

 /**
* There is no end though there is a start in space. ---Infinity.
* It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
* Only the person who was wisdom can read the most foolish one from the history.
* The fish that lives in the sea doesn't know the world in the land.
* It also ruins and goes if they have wisdom.
* It is funnier that man exceeds the speed of light than fish start living in the land.
* It can be said that this is an final ultimatum from the god to the people who can fight.
*
* Steins;Gate
*/ #include <bits/stdc++.h> const int N = ; double k[N], s[N], vv[N], E;
int n; namespace n1 {
inline void solve() {
double v = vv[] + sqrt(E / s[] / k[]);
printf("%.10f\n", s[] / v);
return;
}
} namespace n2 { inline double cal(double v) {
double ans = s[] / v;
double delta = k[] * s[] * (vv[] - v) * (vv[] - v);
//printf("E - delta = %.10f \n", E - delta);
double v2 = vv[] + sqrt((E - delta) / s[] / k[]);
if(v2 < ) return 1e14;
//printf("v2 %.10f = %.10f + sqrt(%.10f / %.10f / %.10f) \n", v2, vv[2], E - delta, s[2], k[2]);
//printf(" = %.10f + %.10f \n", vv[2], sqrt((E - delta) / s[2] / k[2]));
//printf("cal %.10f -> %.10f + %.10f / %.10f \n", v, ans, s[2], v2);
return ans + s[] / v2;
} inline void solve() { double l = , r = vv[] + sqrt(E / s[] / k[]);
for(int i = ; i <= ; i++) {
double mid = (l + r) / ;
//printf("l = %.10f r = %.10f \n", l, r);
double ml = mid - (r - l) / , mr = mid + (r - l) / ;
double vl = cal(ml), vr = cal(mr);
if(vl > vr) {
l = ml;
}
else {
r = mr;
}
}
printf("%.10f\n", cal(r));
return;
}
} int main() {
scanf("%d%lf", &n, &E);
for(int i = ; i <= n; i++) {
scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]);
} if(n == ) {
n1::solve();
return ;
} if(n == ) {
n2::solve();
return ;
} return ;
}

40分代码

学习了一波模拟退火,突然发现这道题可能比较适合乱搞?于是开始疯狂调参最后成功在LOJ和洛谷上A掉了...

考虑如何随机化得出解。我们随机每条路的能量分配即可。

风速为负的每条路有一个能量下限。在此基础上我们把多出来的能量作为自由能量来进行分配。

初始解就是把自由能量均分...之后我们每次随机出两条路a和b,把a的若干能量给b。这里我给的能量是min(a的能量,T * c) * Rand(0, 1)

这里的c是一个参数。于是我们做到了让调整量随着温度的降低而变小。

然后瞎调一波,从0分优化到了100分......中间有很多脑洞大开改参数的过程...

最好玩的是LOJ的AC代码在洛谷上95分,洛谷的AC代码在LOJ上90分...

 // luogu-judger-enable-o2
#include <bits/stdc++.h> const int N = , INF = 0x3f3f3f3f; double k[N], s[N], vv[N], E;
int n; namespace n1 {
inline void solve() {
double v = vv[] + sqrt(E / s[] / k[]);
printf("%.10f\n", s[] / v);
return;
}
} namespace n2 { inline double cal(double v) {
double ans = s[] / v;
double delta = k[] * s[] * (vv[] - v) * (vv[] - v);
double v2 = vv[] + sqrt((E - delta) / s[] / k[]);
if(v2 < ) return 1e14;
return ans + s[] / v2;
} inline void solve() { double l = , r = vv[] + sqrt(E / s[] / k[]);
for(int i = ; i <= ; i++) {
double mid = (l + r) / ;
//printf("l = %.10f r = %.10f \n", l, r);
double ml = mid - (r - l) / , mr = mid + (r - l) / ;
double vl = cal(ml), vr = cal(mr);
if(vl > vr) {
l = ml;
}
else {
r = mr;
}
}
printf("%.10f\n", cal(r));
return;
}
} namespace Fire {
const double eps = 1e-;
double T = , dT = 0.999992;
double nowE[N], temp[N], lm[N];
int test[N]; inline int rd(int l, int r) {
return rand() % (r - l + ) + l;
} inline double Rand() {
return 1.0 * rand() / RAND_MAX;
} inline double calv(int i, double e) {
return vv[i] + sqrt(e / k[i] / s[i]);
} inline double calt(int i, double e) {
return s[i] / (vv[i] + sqrt(e / k[i] / s[i]));
} inline double init() {
for(int i = ; i <= n; i++) {
if(vv[i] < -eps) {
lm[i] = k[i] * s[i] * vv[i] * vv[i];
E -= lm[i];
}
}
double dt = E / n, ans = ;
for(int i = ; i <= n; i++) {
nowE[i] = dt;
ans += calt(i, lm[i] + nowE[i]);
}
return ans;
} inline void solve() {
double ans, fin = 1e14;
srand();
for(int A = ; A <= ; A++) {
ans = init();
fin = std::min(ans, fin);
while(T > eps) {
/// Random a new solution
int a = rd(, n), b = rd(, n);
while(a == b) {
a = rd(, n), b = rd(, n);
}
double deltaE = std::min((long double)nowE[a], (long double)T * 1e8) * Rand();
temp[a] = nowE[a] - deltaE;
temp[b] = nowE[b] + deltaE; double New = ans - calt(a, lm[a] + nowE[a]) - calt(b, lm[b] + nowE[b])
+ calt(a, lm[a] + temp[a]) + calt(b, lm[b] + temp[b]); fin = std::min(fin, New);
if(New < ans || Rand() < exp((ans - New) / T)) {
ans = New;
nowE[a] = temp[a];
nowE[b] = temp[b];
}
T = T * dT;
}
}
printf("%.10f\n", fin);
return;
}
} int main() {
scanf("%d%lf", &n, &E);
for(int i = ; i <= n; i++) {
scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]);
} if(n == ) {
n1::solve();
return ;
} if(n == ) {
n2::solve();
return ;
} Fire::solve();
return ;
}

洛谷AC代码

 #include <bits/stdc++.h>

 const int N = , INF = 0x3f3f3f3f;

 double k[N], s[N], vv[N], E;
int n; namespace n1 {
inline void solve() {
double v = vv[] + sqrt(E / s[] / k[]);
printf("%.10f\n", s[] / v);
return;
}
} namespace n2 { inline double cal(double v) {
double ans = s[] / v;
double delta = k[] * s[] * (vv[] - v) * (vv[] - v);
double v2 = vv[] + sqrt((E - delta) / s[] / k[]);
if(v2 < ) return 1e14;
return ans + s[] / v2;
} inline void solve() { double l = , r = vv[] + sqrt(E / s[] / k[]);
for(int i = ; i <= ; i++) {
double mid = (l + r) / ;
//printf("l = %.10f r = %.10f \n", l, r);
double ml = mid - (r - l) / , mr = mid + (r - l) / ;
double vl = cal(ml), vr = cal(mr);
if(vl > vr) {
l = ml;
}
else {
r = mr;
}
}
printf("%.10f\n", cal(r));
return;
}
} namespace Fire {
const double eps = 1e-;
double T = , dT = 0.99999;
double nowE[N], temp[N], lm[N];
int test[N]; inline int rd(int l, int r) {
return rand() % (r - l + ) + l;
} inline double Rand() {
return 1.0 * rand() / RAND_MAX;
} inline double calv(int i, double e) {
return vv[i] + sqrt(e / k[i] / s[i]);
} inline double calt(int i, double e) {
return s[i] / (vv[i] + sqrt(e / k[i] / s[i]));
} inline double init() {
for(int i = ; i <= n; i++) {
if(vv[i] < -eps) {
lm[i] = k[i] * s[i] * vv[i] * vv[i];
E -= lm[i];
}
}
double dt = E / n, ans = ;
for(int i = ; i <= n; i++) {
nowE[i] = dt;
ans += calt(i, lm[i] + nowE[i]);
}
return ans;
} inline void solve() {
double ans, fin = 1e14;
srand();
for(int A = ; A <= ; A++) {
ans = init();
fin = std::min(ans, fin);
while(T > eps) {
/// Random a new solution
int a = rd(, n), b = rd(, n);
while(a == b) {
a = rd(, n), b = rd(, n);
}
double deltaE = std::min((long double)nowE[a], (long double)T * 1e11) * Rand();
temp[a] = nowE[a] - deltaE;
temp[b] = nowE[b] + deltaE; double New = ans - calt(a, lm[a] + nowE[a]) - calt(b, lm[b] + nowE[b])
+ calt(a, lm[a] + temp[a]) + calt(b, lm[b] + temp[b]); fin = std::min(fin, New);
if(New < ans || Rand() < exp((ans - New) / T)) {
ans = New;
nowE[a] = temp[a];
nowE[b] = temp[b];
}
T = T * dT;
}
}
printf("%.8f\n", fin);
return;
}
} int main() {
scanf("%d%lf", &n, &E);
for(int i = ; i <= n; i++) {
scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]);
} if(n == ) {
n1::solve();
return ;
} if(n == ) {
n2::solve();
return ;
} Fire::solve();
return ;
}

LOJAC代码

调参心得:△T越接近1,就越慢,同时效果越好。初始温度太大可能会超时...

洛谷P2179 骑行川藏的更多相关文章

  1. bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘

    2876: [Noi2012]骑行川藏 Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1033  Solved: ...

  2. 高等数学(拉格朗日乘子法):NOI 2012 骑行川藏

    [NOI2012] 骑行川藏 输入文件:bicycling.in   输出文件:bicycling.out   评测插件 时间限制:1 s   内存限制:128 MB NOI2012 Day1 Des ...

  3. BZOJ 2876 【NOI2012】 骑行川藏

    题目链接:骑行川藏 听说这道题需要一些高数知识 于是膜了一发dalao的题解……然后就没了…… 不要吐槽我的精度TAT……eps设太小了就TLE,大了就Wa……我二分的边界是对着数据卡的…… 下面贴代 ...

  4. 【BZOJ2876】【NOI2012】骑行川藏(数学,二分答案)

    [BZOJ2876][NOI2012]骑行川藏(数学,二分答案) 题面 BZOJ 题解 我们有一个很有趣的思路. 首先我们给每条边随意的赋一个初值. 当然了,这个初值不会比这条边的风速小. 那么,我们 ...

  5. 「NOI2012」骑行川藏

    「NOI2012」骑行川藏 题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨. 川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的 ...

  6. 2876: [Noi2012]骑行川藏 - BZOJ

    Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...

  7. bzoj2876 [Noi2012]骑行川藏

    Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...

  8. bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)

    题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ...

  9. P2179-[NOI2012]骑行川藏【导数,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/P2179 题目大意 给出\(E\)和\(n\)个\(s_i,k_i,u_i\)求一个序列\(v_i\)满足 \[\s ...

随机推荐

  1. mysql获取某个表中除了某个字段名外的所有字段名

    现一个表中有很多字段,但我不想要其中某一个字段,手打出来字段太多,不方便. SELECT GROUP_CONCAT( column_name SEPARATOR ',' ) FROM informat ...

  2. 3.JavaScript-语法、关键保留字及变量

    语法构成区分大小写标识符注释直接量字面量literal关键字保留字变量语法构成JavaScript 的语言核心 ECMAScript. 区分大小写ECMAScript 中的一切,包括变量.函数名和操作 ...

  3. wordpress 图片上传冲突

    网上常见的wordpress图片上传 jQuery('#upload_image_button').click(function() { //formfield并未用上,可能代码遗漏了一段,怀疑和类的 ...

  4. 移动开发基础-学习笔记二-字体图标、less、bootstrap入门

    1.字体图标 1.字体图标都是用svg图片 1.svg图片不失真 2.svg图标由设计师提供 3.为了减少网络请求,会把svg图标转换成字体图标,放到字体文件中,通过字体库的方式使用 2.制作步骤 1 ...

  5. 如何搭建基于C#和 Appium 的 Android自动测试环境

    本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 如果想做手机端的自动化测试,Appium是首选的测试框架,因为网上使 ...

  6. 服务器部署Apache+PHP+MYSQL+Laravel

    1.安装PHP 添加php安装源: sudo apt-get install python-software-properties sudo add-apt-repository ppa:ondrej ...

  7. Python正则表达式很难?一篇文章搞定他,不是我吹!

    1. 正则表达式语法 1.1 字符与字符类 1 特殊字符:.^$?+*{}| 以上特殊字符要想使用字面值,必须使用进行转义 2 字符类 1. 包含在[]中的一个或者多个字符被称为字符类,字符类在匹配时 ...

  8. 在原有数据库中使用 CodeFirst

    一.为当前实体模型启用数据迁移 1.Enable-Migrations -ContextTypeName EME.DBHelper.StoreContext(数据访问上下文) 2. Add-Migra ...

  9. 网络流 之 P2766 最长不下降子序列问题

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  10. [LeetCode] 24. 两两交换链表中的节点

    题目链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs/ 题目描述: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是 ...