洛谷P2179 骑行川藏
什么毒瘤...
解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可。
n = 2的,猜测可以三分。于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间。注意剩余能量不足跑完第二段路的时候,返回INF。
正解是啥拉格朗日乘子法,完全搞不倒...
![](/assets/blank.gif)
![](/assets/blank.gif)
1 /** 2 * There is no end though there is a start in space. ---Infinity. 3 * It has own power, it ruins, and it goes though there is a start also in the star. ---Finite. 4 * Only the person who was wisdom can read the most foolish one from the history. 5 * The fish that lives in the sea doesn't know the world in the land. 6 * It also ruins and goes if they have wisdom. 7 * It is funnier that man exceeds the speed of light than fish start living in the land. 8 * It can be said that this is an final ultimatum from the god to the people who can fight. 9 * 10 * Steins;Gate 11 */ 12 13 #include <bits/stdc++.h> 14 15 const int N = 10010; 16 17 double k[N], s[N], vv[N], E; 18 int n; 19 20 namespace n1 { 21 inline void solve() { 22 double v = vv[1] + sqrt(E / s[1] / k[1]); 23 printf("%.10f\n", s[1] / v); 24 return; 25 } 26 } 27 28 namespace n2 { 29 30 inline double cal(double v) { 31 double ans = s[1] / v; 32 double delta = k[1] * s[1] * (vv[1] - v) * (vv[1] - v); 33 //printf("E - delta = %.10f \n", E - delta); 34 double v2 = vv[2] + sqrt((E - delta) / s[2] / k[2]); 35 if(v2 < 0) return 1e14; 36 //printf("v2 %.10f = %.10f + sqrt(%.10f / %.10f / %.10f) \n", v2, vv[2], E - delta, s[2], k[2]); 37 //printf(" = %.10f + %.10f \n", vv[2], sqrt((E - delta) / s[2] / k[2])); 38 //printf("cal %.10f -> %.10f + %.10f / %.10f \n", v, ans, s[2], v2); 39 return ans + s[2] / v2; 40 } 41 42 inline void solve() { 43 44 double l = 0, r = vv[1] + sqrt(E / s[1] / k[1]); 45 for(int i = 1; i <= 100; i++) { 46 double mid = (l + r) / 2; 47 //printf("l = %.10f r = %.10f \n", l, r); 48 double ml = mid - (r - l) / 6, mr = mid + (r - l) / 6; 49 double vl = cal(ml), vr = cal(mr); 50 if(vl > vr) { 51 l = ml; 52 } 53 else { 54 r = mr; 55 } 56 } 57 printf("%.10f\n", cal(r)); 58 return; 59 } 60 } 61 62 int main() { 63 scanf("%d%lf", &n, &E); 64 for(int i = 1; i <= n; i++) { 65 scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]); 66 } 67 68 if(n == 1) { 69 n1::solve(); 70 return 0; 71 } 72 73 if(n == 2) { 74 n2::solve(); 75 return 0; 76 } 77 78 return 0; 79 }
40分代码
学习了一波模拟退火,突然发现这道题可能比较适合乱搞?于是开始疯狂调参最后成功在LOJ和洛谷上A掉了...
考虑如何随机化得出解。我们随机每条路的能量分配即可。
风速为负的每条路有一个能量下限。在此基础上我们把多出来的能量作为自由能量来进行分配。
初始解就是把自由能量均分...之后我们每次随机出两条路a和b,把a的若干能量给b。这里我给的能量是min(a的能量,T * c) * Rand(0, 1)
这里的c是一个参数。于是我们做到了让调整量随着温度的降低而变小。
然后瞎调一波,从0分优化到了100分......中间有很多脑洞大开改参数的过程...
最好玩的是LOJ的AC代码在洛谷上95分,洛谷的AC代码在LOJ上90分...
![](/assets/blank.gif)
![](/assets/blank.gif)
1 // luogu-judger-enable-o2 2 #include <bits/stdc++.h> 3 4 const int N = 10010, INF = 0x3f3f3f3f; 5 6 double k[N], s[N], vv[N], E; 7 int n; 8 9 namespace n1 { 10 inline void solve() { 11 double v = vv[1] + sqrt(E / s[1] / k[1]); 12 printf("%.10f\n", s[1] / v); 13 return; 14 } 15 } 16 17 namespace n2 { 18 19 inline double cal(double v) { 20 double ans = s[1] / v; 21 double delta = k[1] * s[1] * (vv[1] - v) * (vv[1] - v); 22 double v2 = vv[2] + sqrt((E - delta) / s[2] / k[2]); 23 if(v2 < 0) return 1e14; 24 return ans + s[2] / v2; 25 } 26 27 inline void solve() { 28 29 double l = 0, r = vv[1] + sqrt(E / s[1] / k[1]); 30 for(int i = 1; i <= 100; i++) { 31 double mid = (l + r) / 2; 32 //printf("l = %.10f r = %.10f \n", l, r); 33 double ml = mid - (r - l) / 6, mr = mid + (r - l) / 6; 34 double vl = cal(ml), vr = cal(mr); 35 if(vl > vr) { 36 l = ml; 37 } 38 else { 39 r = mr; 40 } 41 } 42 printf("%.10f\n", cal(r)); 43 return; 44 } 45 } 46 47 namespace Fire { 48 const double eps = 1e-13; 49 double T = 1, dT = 0.999992; 50 double nowE[N], temp[N], lm[N]; 51 int test[N]; 52 53 inline int rd(int l, int r) { 54 return rand() % (r - l + 1) + l; 55 } 56 57 inline double Rand() { 58 return 1.0 * rand() / RAND_MAX; 59 } 60 61 inline double calv(int i, double e) { 62 return vv[i] + sqrt(e / k[i] / s[i]); 63 } 64 65 inline double calt(int i, double e) { 66 return s[i] / (vv[i] + sqrt(e / k[i] / s[i])); 67 } 68 69 inline double init() { 70 for(int i = 1; i <= n; i++) { 71 if(vv[i] < -eps) { 72 lm[i] = k[i] * s[i] * vv[i] * vv[i]; 73 E -= lm[i]; 74 } 75 } 76 double dt = E / n, ans = 0; 77 for(int i = 1; i <= n; i++) { 78 nowE[i] = dt; 79 ans += calt(i, lm[i] + nowE[i]); 80 } 81 return ans; 82 } 83 84 inline void solve() { 85 double ans, fin = 1e14; 86 srand(69); 87 for(int A = 1; A <= 1; A++) { 88 ans = init(); 89 fin = std::min(ans, fin); 90 while(T > eps) { 91 /// Random a new solution 92 int a = rd(1, n), b = rd(1, n); 93 while(a == b) { 94 a = rd(1, n), b = rd(1, n); 95 } 96 double deltaE = std::min((long double)nowE[a], (long double)T * 1e8) * Rand(); 97 temp[a] = nowE[a] - deltaE; 98 temp[b] = nowE[b] + deltaE; 99 100 double New = ans - calt(a, lm[a] + nowE[a]) - calt(b, lm[b] + nowE[b]) 101 + calt(a, lm[a] + temp[a]) + calt(b, lm[b] + temp[b]); 102 103 fin = std::min(fin, New); 104 if(New < ans || Rand() < exp((ans - New) / T)) { 105 ans = New; 106 nowE[a] = temp[a]; 107 nowE[b] = temp[b]; 108 } 109 T = T * dT; 110 } 111 } 112 printf("%.10f\n", fin); 113 return; 114 } 115 } 116 117 int main() { 118 scanf("%d%lf", &n, &E); 119 for(int i = 1; i <= n; i++) { 120 scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]); 121 } 122 123 if(n == 1) { 124 n1::solve(); 125 return 0; 126 } 127 128 if(n == 2) { 129 n2::solve(); 130 return 0; 131 } 132 133 Fire::solve(); 134 return 0; 135 }
洛谷AC代码
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <bits/stdc++.h> 2 3 const int N = 10010, INF = 0x3f3f3f3f; 4 5 double k[N], s[N], vv[N], E; 6 int n; 7 8 namespace n1 { 9 inline void solve() { 10 double v = vv[1] + sqrt(E / s[1] / k[1]); 11 printf("%.10f\n", s[1] / v); 12 return; 13 } 14 } 15 16 namespace n2 { 17 18 inline double cal(double v) { 19 double ans = s[1] / v; 20 double delta = k[1] * s[1] * (vv[1] - v) * (vv[1] - v); 21 double v2 = vv[2] + sqrt((E - delta) / s[2] / k[2]); 22 if(v2 < 0) return 1e14; 23 return ans + s[2] / v2; 24 } 25 26 inline void solve() { 27 28 double l = 0, r = vv[1] + sqrt(E / s[1] / k[1]); 29 for(int i = 1; i <= 100; i++) { 30 double mid = (l + r) / 2; 31 //printf("l = %.10f r = %.10f \n", l, r); 32 double ml = mid - (r - l) / 6, mr = mid + (r - l) / 6; 33 double vl = cal(ml), vr = cal(mr); 34 if(vl > vr) { 35 l = ml; 36 } 37 else { 38 r = mr; 39 } 40 } 41 printf("%.10f\n", cal(r)); 42 return; 43 } 44 } 45 46 namespace Fire { 47 const double eps = 1e-13; 48 double T = 1000, dT = 0.99999; 49 double nowE[N], temp[N], lm[N]; 50 int test[N]; 51 52 inline int rd(int l, int r) { 53 return rand() % (r - l + 1) + l; 54 } 55 56 inline double Rand() { 57 return 1.0 * rand() / RAND_MAX; 58 } 59 60 inline double calv(int i, double e) { 61 return vv[i] + sqrt(e / k[i] / s[i]); 62 } 63 64 inline double calt(int i, double e) { 65 return s[i] / (vv[i] + sqrt(e / k[i] / s[i])); 66 } 67 68 inline double init() { 69 for(int i = 1; i <= n; i++) { 70 if(vv[i] < -eps) { 71 lm[i] = k[i] * s[i] * vv[i] * vv[i]; 72 E -= lm[i]; 73 } 74 } 75 double dt = E / n, ans = 0; 76 for(int i = 1; i <= n; i++) { 77 nowE[i] = dt; 78 ans += calt(i, lm[i] + nowE[i]); 79 } 80 return ans; 81 } 82 83 inline void solve() { 84 double ans, fin = 1e14; 85 srand(2332); 86 for(int A = 1; A <= 1; A++) { 87 ans = init(); 88 fin = std::min(ans, fin); 89 while(T > eps) { 90 /// Random a new solution 91 int a = rd(1, n), b = rd(1, n); 92 while(a == b) { 93 a = rd(1, n), b = rd(1, n); 94 } 95 double deltaE = std::min((long double)nowE[a], (long double)T * 1e11) * Rand(); 96 temp[a] = nowE[a] - deltaE; 97 temp[b] = nowE[b] + deltaE; 98 99 double New = ans - calt(a, lm[a] + nowE[a]) - calt(b, lm[b] + nowE[b]) 100 + calt(a, lm[a] + temp[a]) + calt(b, lm[b] + temp[b]); 101 102 fin = std::min(fin, New); 103 if(New < ans || Rand() < exp((ans - New) / T)) { 104 ans = New; 105 nowE[a] = temp[a]; 106 nowE[b] = temp[b]; 107 } 108 T = T * dT; 109 } 110 } 111 printf("%.8f\n", fin); 112 return; 113 } 114 } 115 116 int main() { 117 scanf("%d%lf", &n, &E); 118 for(int i = 1; i <= n; i++) { 119 scanf("%lf%lf%lf", &s[i], &k[i], &vv[i]); 120 } 121 122 if(n == 1) { 123 n1::solve(); 124 return 0; 125 } 126 127 if(n == 2) { 128 n2::solve(); 129 return 0; 130 } 131 132 Fire::solve(); 133 return 0; 134 }
LOJAC代码
调参心得:△T越接近1,就越慢,同时效果越好。初始温度太大可能会超时...
转载于:https://www.cnblogs.com/huyufeifei/p/10779552.html
洛谷P2179 骑行川藏相关推荐
- [NOI2012]骑行川藏
[NOI2012]骑行川藏 思路一:二分导数 http://www.cnblogs.com/RabbitHu/p/9019762.html 考虑"性价比"即花费单位能量缩短的时间. ...
- bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘
2876: [Noi2012]骑行川藏 Time Limit: 20 Sec Memory Limit: 128 MBSec Special Judge Submit: 1033 Solved: ...
- 2876: [Noi2012]骑行川藏
2876: [Noi2012]骑行川藏 Time Limit: 20 Sec Memory Limit: 128 MBSec Special Judge Submit: 1243 Solved: ...
- 高等数学(拉格朗日乘子法):NOI 2012 骑行川藏
[NOI2012] 骑行川藏 输入文件:bicycling.in 输出文件:bicycling.out 评测插件 时间限制:1 s 内存限制:128 MB NOI2012 Day1 Des ...
- 牛客每日练习----骑行川藏,Lucky Coins,不凡的夫夫
大提琴的声音就像一条河,左岸是我无法忘却的回忆,右岸是我值得紧握的璀璨年华,中间流淌的,是我年年岁岁淡淡的感伤. 链接:https://ac.nowcoder.com/acm/problem/1765 ...
- BZOJ2876 [Noi2012]骑行川藏
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- [BZOJ2876] [NOI2012]骑行川藏
Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...
- bzoj 2876: [Noi2012]骑行川藏 拉格朗日乘子法
题意 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行前设 ...
- bzoj 2876: [Noi2012]骑行川藏 二分+拉格朗日乘数法
题意 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行前设 ...
- bzoj2876: [Noi2012]骑行川藏 :拉格朗日乘数法
题目链接 bzoj2876 题目描述 Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻, ...
最新文章
- 计算机如何理解我们的语言?NLP is fun!
- IoT半导体购并案效果难现 服务器合作案后来居上
- linux删除jpeg动态库,linux如何不用的删除动态库
- 【重点!DFS/记忆化递归 + BFS】LeetCode 133. Clone Graph
- golang中的那些坑
- lazarus中截取整个屏幕画面并保存为指定文件
- 第015讲 仿sohu首页面布局
- git学习之简介(一)
- Android之线性布局的4个重要参数
- 怎么禁止使用计算机的软件,电脑如何禁止程序运行 一键彻底禁止电脑软件运行方法...
- fw150us的linux驱动下载,FAST FW150US2.0无线网卡驱动
- wps根据标题自动生成目录
- 禁止每次打开edge自动在开始菜单创建Microsoft Edge 的 Edge 栏
- IceSword 1.12
- 四旋翼的运动原理及几个飞行问题
- 未来科学技十幻想画计算机,人教版美术教案第七册(全册)
- 分布式Ruby解决之道 - DRb
- linux 导出dump文件
- WebRTC回声抵消模块简要分析
- 大数据时代下,跨境电商如何利用数据实现快速发展
热门文章
- 【第7章】Stable Diffusion WebUI ControlNet基础速成(安装/升级/简介/类别/功能/效果速览)
- 计算机网络技术是学什么 1003无标题,哪个计算机网络技术学校最好
- 蓝桥杯往年常考算法心得
- Rage(PC) Modding Notes
- 虚拟主机服务器E,虚拟主机服务器E
- [TI TDA4 J721E] 屏幕显示中文字符 生成中文字库—Draw2D 模块应用(UTF-8编码)
- Error: 1265, Data truncated for column '列名' at row 1
- 4.2黄金走势行情分析-黄金V型反转能否延续涨势?
- 金山打字通英文课程带注释_设置打字稿中的类型的演练:注释与推理
- 美团商家电话采集软件使用指南