题意:
题目意思就是找到一个环路,使得起点在绕过一圈后升值
思路:
dp,f[t][i][j]表示的是第t次从i到j得到的最大汇率
关键就是枚举起点和终点,最里层枚举中点,这里是无后效性的,那么找到最大的那个中点就是这一次能得到的i,j的值
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn =25;
const int inf = 0x3f3f3f3f;
double mmap[maxn][maxn];
double f[maxn][maxn][maxn];
int path[maxn][maxn][maxn];
int n;
void print2(int t, int i, int j) {
if(t > 1) {
print2(t-1,i,path[t][i][j]);
printf(" %d", path[t][i][j]);
}
else if(t==1)printf("%d", i);
}
bool dp2() {
for(int t=2; t<=n; t++)
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
double m = -1;
int x;
for(int k=1; k<=n; k++){
if(f[t-1][i][k]*mmap[k][j] > m) {
m = f[t-1][i][k]*mmap[k][j];
x = k;
}
}
path[t][i][j] = x;
f[t][i][j] = m;
}
if((f[t][i][i] - 1.01 > 1e-9)) {
print2(t, i, i);
printf(" %d\n", i);
return true;
}
}
return false;
}
int main() {
while(scanf("%d", &n) != EOF) {
memset(f, 0, sizeof(f));
memset(mmap, inf, sizeof(mmap));
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(i != j) {
scanf("%lf", &mmap[i][j]);
f[1][i][j] = mmap[i][j];
}
}
}
if(!dp2())
printf("no arbitrage sequence exists\n");
}
return 0;
}