題意:

給你不同幣值互相交換的匯率,問說可不可以藉由交換幣讓錢從1元增加到1.01元

最多交換n-1次,如果有多種換法就選交換次數最少的,交換次數一樣多的話印任意都可以

 

解法:

用all pair shortest path每次去更新交換s次之後的幣值,然後紀錄是從哪邊轉過來的,檢查自己到自己(交換回自己)有沒有超過1.01,有的話就印出

 

程式碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int n;
double pro[30][30][30];
int pre[30][30][30];
void printPath(int s,int i,int j){
    if(s<=0)return ;
    int sb = pre[s][i][j];
    printPath(s-1,i,sb);
    printf(" %d",sb+1);
}
int main(){
    int i,j;
    int k,s;
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;++i){
            for(j=0;j<n;++j){
                if(i==j)pro[0][i][j] = 1.0;
                else scanf("%lf",&pro[0][i][j]);
                pre[0][i][j] = -1;
            }
        }
        for(s=1;s<n;++s){
            for(i=0;i<n;++i){
                for(j=0;j<n;++j){
                    pro[s][i][j] = -9999;
                }
            }
            for(k=0;k<n;++k){
                for(i=0;i<n;++i){
                    for(j=0;j<n;++j){
                        if(pro[s][i][j] < pro[s-1][i][k]*pro[0][k][j]){
                            pro[s][i][j] = pro[s-1][i][k]*pro[0][k][j];
                            pre[s][i][j] = k;
                        }
                    }
                }
            }
            for(i=0;i<n;++i){
                if(pro[s][i][i] > 1.01)break;
            }
            if(i<n)break;
        }
        if(s==n)puts("no arbitrage sequence exists");
        else {
            printf("%d",i+1);
            printPath(s,i,i);
            printf(" %d\n",i+1);
        }
    }
    return 0;
}

arrow
arrow
    全站熱搜

    alan790712 發表在 痞客邦 留言(0) 人氣()