uva104 - Arbitrage 最小转移步数

Arbitrage 

Background

The use of computers in the finance industry has been marked with controversy lately as programmed trading -- designed to take advantage of extremely small fluctuations in prices -- has been outlawed at many Wall Street firms. The ethics of computer programming is a fledgling field with many thorny issues.

The Problem

Arbitrage is the trading of one currency for another with the hopes of taking advantage of small differences in conversion rates among several currencies in order to achieve a profit. For example, if $1.00 in U.S. currency buys 0.7 British pounds currency, £1 in British currency buys 9.5 French francs, and 1 French franc buys 0.16 in U.S. dollars, then an arbitrage trader can start with $1.00 and earn tex2html_wrap_inline29 dollars thus earning a profit of 6.4 percent.

You will write a program that determines whether a sequence of currency exchanges can yield a profit as described above.

To result in successful arbitrage, a sequence of exchanges must begin and end with the same currency, but any starting currency may be considered.

The Input

The input file consists of one or more conversion tables. You must solve the arbitrage problem for each of the tables in the input file.

Each table is preceded by an integer n on a line by itself giving the dimensions of the table. The maximum dimension is 20; the minimum dimension is 2.

The table then follows in row major order but with the diagonal elements of the table missing (these are assumed to have value 1.0). Thus the first row of the table represents the conversion rates between country 1 and n-1 other countries, i.e., the amount of currency of country i ( tex2html_wrap_inline37 ) that can be purchased with one unit of the currency of country 1.

Thus each table consists of n+1 lines in the input file: 1 line containing n and n lines representing the conversion table.

The Output

For each table in the input file you must determine whether a sequence of exchanges exists that results in a profit of more than 1 percent (0.01). If a sequence exists you must print the sequence of exchanges that results in a profit. If there is more than one sequence that results in a profit of more than 1 percent you must print a sequence of minimal length, i.e., one of the sequences that uses the fewest exchanges of currencies to yield a profit.

Because the IRS (United States Internal Revenue Service) notices lengthy transaction sequences, all profiting sequences must consist of n or fewer transactions where n is the dimension of the table giving conversion rates. The sequence 1 2 1 represents two conversions.

If a profiting sequence exists you must print the sequence of exchanges that results in a profit. The sequence is printed as a sequence of integers with the integer i representing the tex2html_wrap_inline51 line of the conversion table (country i). The first integer in the sequence is the country from which the profiting sequence starts. This integer also ends the sequence.

If no profiting sequence of n or fewer transactions exists, then the line

no arbitrage sequence exists
should be printed.

Sample Input

3
1.2 .89
.88 5.1
1.1 0.15
4
3.1    0.0023    0.35
0.21   0.00353   8.13 
200    180.559   10.339
2.11   0.089     0.06111
2
2.0
0.45

Sample Output

1 2 1
1 2 4 1
no arbitrage sequence exists

  给出货币的汇率,问一种货币换成别的最后再换回来能增长0.01%的最少转移步数是多少。

  这个就像概率论里那个马尔可夫链(从i到j转移k步的所有状态也是从i到m转移n步,再从m到j转移k-n步的所有状态),类似floyd,只不过多了个步数。设f[i][j][step]为i到j走step步增长最多的情况,状态转移方程是f[i][j][step]=min(f[i][k][step-1]*f[k][j][1])。一旦找到满足条件的就直接打印。要打印路径,用path[i][j][step]代表从i到j走step步最后一步的起点(path[i][j][1]=i),递归打印。


#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#define INF 0x3f3f3f3f
#define MAXN 25
#define pii pair<int,int>
using namespace std;
int N;
double f[MAXN][MAXN][MAXN];
int path[MAXN][MAXN][MAXN];

void print_path(int i,int j,int step){
    if(step<=0) return;
    print_path(i,path[i][j][step],step-1);
    printf("%d ",path[i][j][step]);
}
void DP(){
    int i,j,k,step;
    for(step=2;step<=N;step++){
        for(k=1;k<=N;k++)
            for(i=1;i<=N;i++)
                for(j=1;j<=N;j++) if(f[i][j][step]<f[i][k][step-1]*f[k][j][1]){
                    f[i][j][step]=f[i][k][step-1]*f[k][j][1];
                    path[i][j][step]=k;
                }
        for(i=1;i<=N;i++) if(f[i][i][step]>1.01){
            print_path(i,i,step);
            printf("%d\n",i);
            return;
        }
    }
    printf("no arbitrage sequence exists\n");
    return;
}
int main(){
    freopen("in.txt","r",stdin);
    while(scanf("%d",&N)!=EOF){
        memset(f,0,sizeof(f));
        int i,j;
        for(i=1;i<=N;i++)
            for(j=1;j<=N;j++){
                if(i!=j){
                    scanf("%lf",&f[i][j][1]);
                    path[i][j][1]=i;
                }
            }
        DP();
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值