104 - Arbitrage
这道题费了我相当的时间。
题目要求找到一个profit > 1.01的套汇序列,但有多个的情况时,要求输出序列最短的一条。
开始觉得很像Floyd-Warshall 算法,但试着开写了才发现,对于怎么控制得到最短序列非常有玄机。最后还是在UVa的论坛里找到了一个好帖,给出了一个 O(n4) 的算法,并给了非常详细的解释。原帖在这里,请看 gits 的回帖。
用 profit(i, j, step) 存放“由 i 经过 step 步套汇得到 j 可以得到的最大profit值”。则有以下递推式:
profit(i, j, step) = profit(i, k, step-1) * profit(k, j, 1); // 当profit(i, k, step-1) * profit(k, j, 1) > profit(i, j, step)
递推初始值:profit(i, i, 1) = 1.0
另外,使用 Floyd-Warshall 算法往往要记录回溯路径(除非不需要得到的序列)。
这里使用一个through(i, j, step) 来存放“若由 i 经过 step 步套汇得到 j,j 前一个货币是 k”。这样可以在最后用一个stack把这个反向表示的路径反转过来输出。
最后要说的是在 Floyd-Warshall 算法运行过程中一但发现算出的 profit > 1.01,立即中止运算并输出会使结果快上一倍左右。但对整体算法复杂度没有太大影响。
返回 Volume I 索引
返回总索引
// // 104 - Arbitrage // Copyright (c) 2010 by Bo-wen Feng // balonfan@gmail.com // #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <vector> #include <string> #include <sstream> #include <cstdio> #include <cmath> #include <limits> #include <utility> #ifndef ONLINE_JUDGE #include <fstream> std::ifstream cin("in.txt"); std::ofstream cout("out.txt"); // std::ofstream cout(stdout); #else #include <iostream> #endif typedef long long llong; typedef unsigned long long ullong; typedef long double ldouble; using namespace std; #define MAXN 20 double profit [MAXN][MAXN][MAXN + 1]; int through[MAXN][MAXN][MAXN + 1]; int nDim; int main(int argc, char* argv[]) { for(;;) { if(!(cin>> nDim)) break; for(int i = 0; i < nDim; ++i) for(int j = 0; j < nDim; ++j) for(int step = 2; step <= nDim; ++step) profit[i][j][step] = 0.0; // get the input for(int i = 0; i < nDim; ++i) { profit[i][i][1] = 1; through[i][i][1] = i; for(int j = 0; j < nDim - 1; ++j) { int k = j < i ? j : j+1; cin>> profit[i][k][1]; through[i][k][1] = i; } } int start = -1; int minStep = nDim + 1; // for each step, we use Floyd-Warshall algorithm to find max profit for(int step = 2; step <= nDim; ++step) for(int k = 0; k < nDim; ++k) for(int i = 0; i < nDim; ++i) for(int j = 0; j < nDim; ++j) { double newProfit = profit[i][k][step-1] * profit[k][j][1]; if(newProfit > profit[i][j][step]) { profit[i][j][step] = newProfit; through[i][j][step] = k; if(i == j && profit[i][j][step] > 1.01) { // if we find one, go print directly start = i; minStep = step; goto result; } } } result: if(start == -1) { cout<< "no arbitrage sequence exists/n"; } else { // reverse and output stack<int> path; path.push(start); int end = start; for(int s = minStep; s >= 2; --s) { end = through[start][end][s]; path.push(end); } cout<< (start + 1); while(!path.empty()) { cout<< " "<< (1 + path.top()); path.pop(); } cout<< "/n"; } } return 0; }
104 - Arbitrage相关推荐
- π-Algorithmist分类题目(3)
原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(3) Probability ...
- π-Algorithmist分类题目(2)
原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(2) Set Theory U ...
- UVa Online Judge 工具網站
UVa Online Judge 工具網站 转自http://www.csie.ntnu.edu.tw/~u91029/uva.html Lucky貓的ACM園地,Lucky貓的 ACM 中譯題目 M ...
- 提取了下刘汝佳推荐的题号...
今天闲来没事上uva oj提取了下刘汝佳推荐的acm题号,原始数据如下: Volume 0. Getting Started 10055 - Hashmat the Brave Warrior ...
- 零起点学算法104——第几天?
零起点学算法104--第几天? Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lld Description 给定一个日期,输 ...
- I - Arbitrage POJ - 2240
I - Arbitrage POJ - 2240 题意: 利用汇率之间的差价判断是否可以赚钱 思路: 利用 spfa 跑最长路(即松弛条件改为取更大的值),判断是否存在正环,存在则可以赚钱 #incl ...
- 【tensorflow】OP_REQUIRES failed at variable_ops.cc:104 Already exists: Resource
如下代码片段 outputs = tf.keras.layers.Bidirectional(tf.keras.layers.GRU(units=half_depth, use_bias=False, ...
- 腾讯绝地求生手游席卷全球,104个国家地区IOS登顶
PUBG Mobile 腾讯旗下的PUBG Mobile在20日上线后,迅速成为世界级爆款游戏,在104个国家和地区登顶. PUBG Mobile 腾讯旗下的光子工作室这次可算是在全球的火爆了一把.这 ...
- 领扣-104/111 二叉树的最大深度 Maximum Depth of Binary Tree MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
最新文章
- Sharding-Jdbc 实现读写分离 + 分库分表,写得太好了!
- sdr 软件_SDR 软件定义的无线电
- 彻底理解cookie,session,localStorage(附代码)
- 知识点小记之转义字符
- Uipath 学习栏目基础教学:6Uipath发送邮件
- 转:PHP 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
- vs code html table,vs Code 快速生成代码
- Win10 jdk的安装以及环境变量的配置,及需要注意的坑
- Android 如何调用系统默认浏览器访问
- Java如何随机出石头剪刀布_JAVA编程实现石头剪刀布
- 实战 RocketMQ 流量削峰,怎么能错过这一篇!
- Bailian2855 计算概论(刘志敏老师班)ACM测试题1【椭圆】
- Linux下C语言的调试器 Gdb
- java对象中方法的存储原理_垃圾收集机制的基本原理及方法
- Qt QPushButton 解决触摸屏点击 pressed样式表无效
- 大学微积分考试能用计算机吗,AP微积分考试需要什么样的计算器?
- MATLAB元胞自动机
- mac如果装win系统运行,虚拟机好还是双系统好?
- 5G学习之路——认识CU、DU
- lt;#37;= %、lt;#37; %、lt;#37;@ %、lt;#37;:%和lt;#37;# %的区别
热门文章
- 学不可以已--我一年Java之路的回顾,反思以及展望(上)
- Java:求出1~999999之间的所有“水仙花数”并输出
- multi接口的使用
- 除甲醛产品哪个好?除甲醛产品十大品牌第一名
- 【Python入门教程】第38篇 filter()函数
- 报错:Elsevier LaTeX编译:Mismatched LaTeX support files detected
- 一 你好啊,我叫阿丁1
- [Python]小甲鱼Python视频第019课(函数:我的地盘听我的)课后题及参考解答
- 网易互娱2018校招游戏研发工程师在线笔试
- tailwindcss模板_如何开始使用TailwindCSS