这道题费了我相当的时间。

题目要求找到一个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 步套汇得到 jj 前一个货币是 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相关推荐

  1. π-Algorithmist分类题目(3)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(3) Probability ...

  2. π-Algorithmist分类题目(2)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(2) Set Theory U ...

  3. UVa Online Judge 工具網站

    UVa Online Judge 工具網站 转自http://www.csie.ntnu.edu.tw/~u91029/uva.html Lucky貓的ACM園地,Lucky貓的 ACM 中譯題目 M ...

  4. 提取了下刘汝佳推荐的题号...

    今天闲来没事上uva oj提取了下刘汝佳推荐的acm题号,原始数据如下: Volume 0. Getting Started    10055 - Hashmat the Brave Warrior ...

  5. 零起点学算法104——第几天?

    零起点学算法104--第几天? Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lld Description 给定一个日期,输 ...

  6. I - Arbitrage POJ - 2240

    I - Arbitrage POJ - 2240 题意: 利用汇率之间的差价判断是否可以赚钱 思路: 利用 spfa 跑最长路(即松弛条件改为取更大的值),判断是否存在正环,存在则可以赚钱 #incl ...

  7. 【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, ...

  8. 腾讯绝地求生手游席卷全球,104个国家地区IOS登顶

    PUBG Mobile 腾讯旗下的PUBG Mobile在20日上线后,迅速成为世界级爆款游戏,在104个国家和地区登顶. PUBG Mobile 腾讯旗下的光子工作室这次可算是在全球的火爆了一把.这 ...

  9. 领扣-104/111 二叉树的最大深度 Maximum Depth of Binary Tree MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

最新文章

  1. Sharding-Jdbc 实现读写分离 + 分库分表,写得太好了!
  2. sdr 软件_SDR 软件定义的无线电
  3. 彻底理解cookie,session,localStorage(附代码)
  4. 知识点小记之转义字符
  5. Uipath 学习栏目基础教学:6Uipath发送邮件
  6. 转:PHP 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
  7. vs code html table,vs Code 快速生成代码
  8. Win10 jdk的安装以及环境变量的配置,及需要注意的坑
  9. Android 如何调用系统默认浏览器访问
  10. Java如何随机出石头剪刀布_JAVA编程实现石头剪刀布
  11. 实战 RocketMQ 流量削峰,怎么能错过这一篇!
  12. Bailian2855 计算概论(刘志敏老师班)ACM测试题1【椭圆】
  13. Linux下C语言的调试器 Gdb
  14. java对象中方法的存储原理_垃圾收集机制的基本原理及方法
  15. Qt QPushButton 解决触摸屏点击 pressed样式表无效
  16. 大学微积分考试能用计算机吗,AP微积分考试需要什么样的计算器?
  17. MATLAB元胞自动机
  18. mac如果装win系统运行,虚拟机好还是双系统好?
  19. 5G学习之路——认识CU、DU
  20. lt;#37;= %、lt;#37; %、lt;#37;@ %、lt;#37;:%和lt;#37;# %的区别

热门文章

  1. 学不可以已--我一年Java之路的回顾,反思以及展望(上)
  2. Java:求出1~999999之间的所有“水仙花数”并输出
  3. multi接口的使用
  4. 除甲醛产品哪个好?除甲醛产品十大品牌第一名
  5. 【Python入门教程】第38篇 filter()函数
  6. 报错:Elsevier LaTeX编译:Mismatched LaTeX support files detected
  7. 一 你好啊,我叫阿丁1
  8. [Python]小甲鱼Python视频第019课(函数:我的地盘听我的)课后题及参考解答
  9. 网易互娱2018校招游戏研发工程师在线笔试
  10. tailwindcss模板_如何开始使用TailwindCSS