题目:货币兑换,问能否找到一条将某种货币兑换成1.01倍以上的回路,如果不止一条,输出最短的。
分析:动态规划(dp)。开始以为是最短路(⊙v⊙)嗯。
定义状态:f(t,u,v)为路径长度为t时,从u到v所能获得的最大收益;
状态转移:f(t,u,v)= max(f(t-1,u,k)* f(1,u,v));
存储路径输出即可。
说明:UVa 和 uhunt 都上不去了(⊙v⊙)。。。
#include <cstring>
#include <cstdio>
double value[25][25][25];
int front[25][25][25];
void output(int t, int u, int v)
{
if (t >= 1) {
output(t-1, u, front[t][u][v]);
printf(" %d", v);
}else {
printf("%d", u);
}
}
int dp(int n)
{
for (int t = 2; t <= n; ++ t) {
for (int u = 1; u <= n; ++ u) {
for (int v = 1; v <= n; ++ v) {
value[t][u][v] = -1.0;
for (int k = 1; k <= n; ++ k) {
if (value[t][u][v] < value[t-1][u][k]*value[1][k][v]) {
value[t][u][v] = value[t-1][u][k]*value[1][k][v];
front[t][u][v] = k;
}
}
}
if (value[t][u][u] > 1.01) {
output(t, u, u);
printf("\n");
return true;
}
}
}
return false;
}
int main()
{
int n;
while (~scanf("%d",&n)) {
for (int i = 1; i <= n; ++ i) {
for (int j = 1; j <= n; ++ j) {
if (i == j) {
value[1][i][j] = 1.0;
}else {
scanf("%lf",&value[1][i][j]);
}
}
}
if (!dp(n)) {
printf("no arbitrage sequence exists\n");
}
}
return 0;
}