POJ 2240 利率变权值 Floyd变乘法

本文介绍了一种通过检测货币兑换率是否存在盈利机会的方法。利用类似Floyd算法的动态规划思想,构建货币之间的兑换网络,判断是否存在一条路径使初始货币经过一系列兑换后增值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arbitrage
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 20575 Accepted: 8768

Description

Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 1 US Dollar buys 0.5 British pound, 1 British pound buys 10.0 French francs, and 1 French franc buys 0.21 US dollar. Then, by converting currencies, a clever trader can start with 1 US dollar and buy 0.5 * 10.0 * 0.21 = 1.05 US dollars, making a profit of 5 percent.

Your job is to write a program that takes a list of currency exchange rates as input and then determines whether arbitrage is possible or not.

Input

The input will contain one or more test cases. Om the first line of each test case there is an integer n (1<=n<=30), representing the number of different currencies. The next n lines each contain the name of one currency. Within a name no spaces will appear. The next line contains one integer m, representing the length of the table to follow. The last m lines each contain the name ci of a source currency, a real number rij which represents the exchange rate from ci to cj and a name cj of the destination currency. Exchanges which do not appear in the table are impossible.
Test cases are separated from each other by a blank line. Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line telling whether arbitrage is possible or not in the format "Case case: Yes" respectively "Case case: No".

Sample Input

3
USDollar
BritishPound
FrenchFranc
3
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar

3
USDollar
BritishPound
FrenchFranc
6
USDollar 0.5 BritishPound
USDollar 4.9 FrenchFranc
BritishPound 10.0 FrenchFranc
BritishPound 1.99 USDollar
FrenchFranc 0.09 BritishPound
FrenchFranc 0.19 USDollar

0

Sample Output

Case 1: Yes
Case 2: No

题意:给你一些货币比如A,B,C,然后给你他们之间存在的对换关系,如A可以换0.5个B,B可以换10个C,C可以换2个A等.然后问你是否存在一种对换可以使得1个A可以换到大于1个A的钱.

分析:

       首先把每个货币的单词映射成一个数字,表示该货币的编号.然后其实本题用到了类似Floyd的动态规划思想.

       首先假设货币1对换货币2 比率为a,货币2对换货币3 比率为b.

那么货币1对换货币3比率为多少呢?
为a*b.

      
现在我们希望货币能增值,所以如果货币1换货币3 有两种比率分别为0,5和0,6.那么我们明显放弃0.5那个,只需要用0.6的比率即可.所以这道题就成了求一个有向图的任意两点的最大兑换比例,不过这个比例不是相加运算了,而是相乘运算.

       且现在不是最小值最优了,而是最大值最优了. 其实原理就是Floyd的动态规划原理.其实就是传递闭包,证明省略,可以参考Floyd的证明过程.



#include <iostream>
#include <map>

using namespace std;
const int maxn = 35;
const int INF = 0x3ffffff;
map<string,int> Map;
double e[maxn][maxn];

int main(){
    string s1,s2;
    int i ,j , k;
    double rate;
    int cases = 1;
    int n,m;
    while(cin>>n&&n){
        int cnt = 0;

        //初始化权值,乘以本身的利率是1
        for(i = 0;i<n;i++){
            for(j=0;j<n;j++){
                if(i==j)
                    e[i][j]=1;
                else
                    e[i][j]=-INF;
            }
        }
        for(i=0;i<n;i++){
            cin>>s1;
            Map[s1] = cnt;//初始化点的编号
            cnt++;
        }
        cin>>m;
        for(i=0;i<m;i++){
            cin>>s1>>rate>>s2;
            e[Map[s1]][Map[s2]]=rate;
        }
        //Floyd思想
        for(k=0;k<n;k++)
            for(i=0;i<n;i++)
              for(j=0;j<n;j++)
                  if(e[i][j]<e[i][k]*e[k][j]) //初始化e为-INF的原因,方便取最大值
                     e[i][j]=e[i][k]*e[k][j];
        int flag = 0;
        //遍历所有本钱
        for(i=0;i<n;i++){
            if(e[i][i]>1)
                flag=1;
        }
        if(flag)
            cout<<"Case "<<cases<<": Yes"<<endl;
      else cout<<"Case "<<cases<<": No"<<endl;
      cases++;
   
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值