UVa Problem 104 - Arbitrage

来源:互联网 发布:ubuntu下openstack搭建 编辑:程序博客网 时间:2024/04/29 23:01
// UVa Problem 104 - Arbitrage// Verdict: Accepted// Submission Date: 2011-12-22// UVa Run Time: 0.068s//// 版权所有(C)2011,邱秋。metaphysis # yeah dot net//// [解题方法]// 本质是求一个最小环,要求边权的积大于或等于 1.02,可以使用动态规划和 Floyd-Warshall 算法(实际上// Floyd-Warshall 本身就已经使用了动态规划的思想)来解决本题。//// 用 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#include <iostream>using namespace std;#define MAXN 20double profit[MAXN + 1][MAXN + 1][MAXN + 1];int memo[MAXN + 1][MAXN + 1][MAXN + 1];int n;void output(int start, int end, int step){if (step >= 2){output(start, memo[start][end][step], step - 1);cout << " " << memo[start][end][step];}}int main(int argc, char *argv[]){while (cin >> n){for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)for (int k = 1; k <= n; k++)profit[i][j][k] = 0.0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (i == j){profit[i][j][1] = 1;memo[i][j][1] = i;}else{cin >> profit[i][j][1];memo[i][j][1] = i;}int start, steps;bool arbitrage = false;for (int step = 2; step <= n; step++)for (int k = 1; k <= n; k++)for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++){double temp = profit[i][k][step - 1] * profit[k][j][1];if (temp > profit[i][j][step]){profit[i][j][step] = temp;memo[i][j][step] = k;if (i == j && profit[i][j][step] > 1.01){arbitrage = true;start = i;steps = step;goto out;}}}out:if (arbitrage){cout << start;output(start, start, steps);cout << " " << start << endl;}elsecout << "no arbitrage sequence exists" << endl;}return 0;}
原创粉丝点击