题目大意:
给你两两国家之间的汇率,要求你从任何一个国家出发,身上带着1(单位不明),然后回到这个国家时,身上的钱能够> 1.01.并且如果这样的路径有多条的话,希望的到的是最短的路径,并且还有要求你输出这个最短的路径。
思路:
利用DP去求出从i到j中间经过l个国家后所获得的金钱。
那么dp[i][j][1]表示的是从i到j国家之间的汇率,
所以dp[i][j][l] = max(dp[i][j][l],dp[i][k][l - 1]*dp[k][j][1]);
如果出现满足从一个国家回到这个国家身上的钱 > 1.01的就退出循环,因为这样那个可以保证图经的国家最少,即可以找到最短了路径。
代码:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
const int N =25;
double dp[N][N][N],p[N][N][N];
int n;
void print(int i,int j,int l) {
if(l == 0){
printf("%d",i);
return;
}
print(i,p[i][j][l],l - 1);
printf(" %d",j);
return;
}
void DP() {
int l;
int m;
for(l = 2; l <= n; l++) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
if(dp[i][j][l] < dp[i][k][l - 1] *dp[k][j][1]) {
dp[i][j][l] = dp[i][k][l - 1]*dp[k][j][1];
p[i][j][l] = k;
}
int i;
for(i = 1; i <= n; i++)
if(dp[i][i][l] > 1.01) {
m = i;
break;
}
if(i <= n)
break;
}
if(l > n)
printf("no arbitrage sequence exists");
else
print(m,m,l);
printf("\n");
}
int main() {
while(scanf("%d",&n) != EOF) {
memset(dp,0,sizeof(dp));
memset(p,-1,sizeof(p));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(i == j)
dp[i][j][1] = 1;
else
scanf("%lf",&dp[i][j][1]);
p[i][j][1] = j;
}
DP();
}
return 0;
}