original title Chinese translation: (from Lucky cat)
Arbitrage
The so-called "triangular set of arbitrage" is the transaction of money in a few foreign currencies, expecting a little profit from the difference. For example: 1 dollars can buy 0.7 British pound, 1 British pound can buy 9.5 French lang, 1 yuan fa lang can buy 0.16 dollars. So if we convert 1 dollars into British pound, and then swap the British pound for the French dollar, and then return it to US dollars, then the final dollar will be: 1*0.7*9.5*0.16=1.064 dollars. That is to say, we can get a $0.064 from the exchange, which is about 6.4%.
Please write a program to find out if there is such a situation, you can obtain the benefits as described above.
To produce a successful set of money, in the process of the foreign currency, the beginning of the currency must be equal to the last currency species. But from what start can be.
Input
Input contains multiple test materials.
In the first column of each test, there is an integer n (2 <= n <= 20) representing the total number of coins.
The next n column represents the exchange rate conversion table for this n foreign currency. Each column has n-1 numbers. This n-1 means that the currency of $1 can be converted to a different currency (by itself, of course, 1, so it will not appear). So the 1th column of the n-1 number of the 1th foreign currency 1 yuan can be replaced, 2nd foreign currency, 3rd foreign currency, 4th foreign currency ... The amount of the first N foreign currency. and the 2nd column of the n-1 number of the 2nd foreign currency 1 Yuan can be replaced, 1th foreign currency, 3rd foreign currency, 4th foreign currency ... The amount of the first N foreign currency. According to this kind of push, the n-1 number of nth column is divided to represent the nth foreign currency 1 yuan can be replaced, the 1th foreign currency, the 2nd foreign currency, the 3rd foreign currency ... N-1 The amount of foreign currency.
Please refer to sample Input.
Output
One column for each group of tests represents a currency conversion, and the set-off is greater than 1% (> 0.01). " If there is more than one conversion to gain over 1% of the benefits, please output the least number of conversion times. If there is more than one conversion, then any one can. Please note: Only the minimum number of conversion times is required here, and there is no requirement to maximize the gain, as long as it is greater than 1%.
In addition, the tax Bureau can only be converted to n times (n is the number of the currency). Like 1, 2, 1 this conversion is 2.
If there is no gain over 1% in the conversion of n times, please input no arbitrage sequence exists.
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
#include <bits/stdc++.h> using namespace std;
FStream in,out;
const int inf=99999;
Double dp[21][21][21],mark[21][21][21];
Double rate[21][21];
int p;
void Get_path (int i,int j,int s) {if (s==0) {cout<<i;
Return
} get_path (I,MARK[I][J][S],S-1);
cout<< "" <<j;}
int main () {Ios::sync_with_stdio (false);
int n,s;
while (cin>>n) {memset (mark,0,sizeof (Mark));
Memset (Dp,0,sizeof (DP));
for (int i=1;i<=n;i++) {for (int j=1;j<=n;j++) {if (i==j)
{rate[i][j]=1;
Dp[j][i][1]=1;
} else {cin>>rate[i][j];
DP[I][J][1]=RATE[I][J];
Mark[i][j][1]=j;
}}} for (s=2;s<=n;s++) {for (int k=1;k<=n;k++) {for (int. i=1;i<=n;i++) {for (int j=1;j<=n;j++)
{if (Dp[i][j][s]<dp[i][k][s-1]*rate[k][j]) {
DP[I][J][S]=DP[I][K][S-1]*RATE[K][J];
Mark[i][j][s]=k;
}}}} int i;
for (i=1;i<=n;i++) {if (dp[i][i][s]>1.01) {p=i;
Break
}} if (i<=n) break;
} if (s>n) cout<< "No arbitrage sequence exists";
else Get_path (p,p,s);
cout<<endl;
} return 0;
}
Answer:
In Lrj's White book, Thinking about finding the problem of the graph theory to do, the result is a dynamic planning = =orz
This question thought for a long while, thought of using the floyed algorithm improvement, but stuck in how to ensure that the arbitrage less than 0.01 cases. The beginning of the idea set DP[I][J] for the interest rate from the I-currency arbitrage to J-coins, set sum[i][j] for the interchange from I arbitrage to J, and then plan on calculating sum[i][j at the same time for each calculation dp[i][j] satisfying more than 0.01, and finding the smallest, Think of the half-way to find that the idea is flawed, because the dp[i][j] in the state transfer is the condition referred to Sum[i][j], so dp[i][j] is not the optimal solution. Later thought to increase the state of the method, but did not continue to think, if you continue to think might be made, unfortunately such a good question. To summarize a sentence:
If a sub-problem is constrained and cannot be transferred to the optimal solution, or requires an optimal value under a condition s dp[i][j][k] ..., then first consider adding a state s into dp[i][j][k] ... [s] to process.
The code references the Great God's blog: http://www.cnblogs.com/scau20110726/archive/2012/12/26/2834674.html
Here's a quote from the Great God Blog:
DP build (modeled Floyd)
This problem is difficult to say, now think it seems not too difficult, because you want to complicate. In fact, the requirements of this problem is not much, it is only required to the final conversion back to the start of the kind of coins and profit greater than 0.01, and the number of conversions can not exceed n times, the fewer conversions the better, and then output the shortest path. Note: The topic does not say that you want to profit the most, is only a profit >=0.01 can, in addition, the topic on the path and there is no special requirements, only the requirements can not exceed n, in the same length of the path of any one can be.
So let's just grab a little bit: the number of conversions ...
In other words, every time we convert, we look for all the currencies, Look at them back to their time the profit of those currencies has been greater than 0.01, if the profit of the currency has been greater than 0.01, then our algorithm is over, the output of this currency conversion path (even if there are more than 0.01 of the profit of a variety of currencies are good, the output of which currency is OK, because the topic is not required)
We should write an outermost loop that represents the first few conversions, which cannot be greater than n, because only n times can be converted, whether successful or failed
Then, using the number of conversions to do the outermost loop, this strategy is correct, for what? Assuming that the current conversion is i+1, then it is necessary to use the information of the conversion of the first I ...
Why is it. We can look back at the nature of Floyd.
The original Floyd is a three-dimensional array dp[k][i][j]=max{dp[k-1][i][j], Dp[k-1][i][k]+dp[k-1][k][j]}
We usually write the Floyd are two-dimensional, in fact, three-dimensional compression back, nothing can compress the highest of that one dimension. It is possible to look at the state transfer equation alone, and the current DP[K][I][J] is only related to the previous dp[k-1][][, which is the information derived from the previous information. It's just like our scrolling array.
So let's define a state Dp[i][j][s] I and J are the first and second currencies, S is the number of conversions, s from 1 to N. That is, in the first S conversion, an attempt is made to convert the inside J
So what is the state transition equation? dp[i][j][s]=max{dp[i][j][s-1], Dp[i][k][s-1]*g[k][j]}
G[I][J] is the input data is the conversion rate between 22 currencies, in fact, can be saved in dp[i][j][0]
So what does this state-transfer equation mean? That is, after the previous conversion, now want to convert from I to J, trying to pass K, see if you can make the value larger, can be larger (big must not be a disadvantage, because the topic also did not require money into how much, just ask for more than 0.01, so the current if you can get bigger, it certainly becomes larger)