这道题的题意是:给出n种国家的货币汇率,必定金额的某种货币通过一系列汇率变换后再换成原来货币,金额增长了,求出这样的一个变换,要求变换步数最少。java
因为数据量不大,咱们能够直接用动规+floyd解决,设f[p][i][j]为由i到j通过p次转换所能达到的最大汇率乘积,每循环一次p咱们就扫描一遍f[p][i][i],若是有大于1的状况就直接打印结果便可。spa
在记录路径时用path[p][i][j]记录第k次转换的初始位置,打印时采用递归的方式。code
3
orm
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
it
1 2 1
io
1 2 4 1
no arbitrage sequence existsclass
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Arbitrage { public static int n; public static float[][][] f; public static int[][][] path; public static void floyd() { int p, i, j, k; p = i = j = k = 0; for (p = 1; p < n; p++) { for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) for (k = 0; k < n; ++k) {//找到f(p-1)到f(p)转换的最大值保存下来,同时保存转换路径 if (f[p - 1][i][k] * f[0][k][j] > f[p][i][j]) { f[p][i][j] = f[p - 1][i][k] * f[0][k][j]; path[p][i][j] = k; } } for (int m = 0; m < n; ++m) { if (f[p][m][m] > 1) { // System.out.println("find some thing"); print(m, m, p); System.out.println(); } } } } public static void print(int i, int j, int p) { if (p == 0) { System.out.print(i+" ");//打印起点 System.out.print(j+" ");//打印起点后打印途径点 } else { print(i, path[p][i][j], p - 1);//先遍历到起点再开始打印 System.out.print(j+" ");//打印途径点 } } public static void main(String[] args) { try { FileInputStream fis = new FileInputStream(new File("D:/a.txt")); StreamTokenizer st = new StreamTokenizer(new BufferedReader( new InputStreamReader(fis))); while (st.nextToken() != StreamTokenizer.TT_EOF) { System.out.println("-------"); n = (int) st.nval; f = new float[n][n][n]; path = new int[n][n][n]; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i == j) f[0][i][j] = 1; else { st.nextToken(); f[0][i][j] = (float) st.nval; } } } floyd(); } } catch (Exception e) { e.printStackTrace(); } } }