zoukankan      html  css  js  c++  java
  • uva 104(变形floyd)

    题意:有若干种货币,并给出其互相交换的汇率,问能不能找到一个小于n的环使起始点的货币交换之后增长超过1%。

    思路:这道题坑了两个小时,一开始看他数据量比较小才20就想用搜索剪枝,后来仔细算了一下还是会超时的,再后来就去看解题报告了。果断想的方向就错了,其实是动态规划状态一看就知道该怎么写了=。=和floyd很像的。dis[i][j][k]表示从i到j交换k次所获得的最大收益。然后四重循环每次枚举中间结点v并从dis[i][v][k-1]转移过来。别忘了转的时候要记录路径。算好之后从1-k扫描一有超过1.01就打印路径即可。

    代码如下:(我写的比较长0.0)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <utility>
     7 #include <stack>
     8 #include <queue>
     9 #include <vector>
    10 #define INF 500001
    11 #define LEN 110
    12 
    13 using namespace std;
    14 
    15 int n, path[LEN][LEN][LEN];
    16 double Map[LEN][LEN], dis[LEN][LEN][LEN];
    17 
    18 void floyd()
    19 {
    20     memset(dis, 0, sizeof dis);
    21     memset(path, 0, sizeof path);
    22     for(int i=1; i<=n; i++){
    23         for(int j=1; j<=n; j++){
    24             dis[i][j][1] = Map[i][j];
    25             path[i][j][1] = i;
    26         }
    27     }
    28     for(int k=2; k<=n; k++){
    29         for(int v=1; v<=n; v++){
    30             for(int i=1; i<=n; i++){
    31                 for(int j=1; j<=n; j++){
    32                     if(dis[i][j][k]<dis[i][v][k-1]*dis[v][j][1]){
    33                         dis[i][j][k] = dis[i][v][k-1]*dis[v][j][1];
    34                         path[i][j][k] = v;
    35                     }
    36                 }
    37             }
    38         }
    39     }
    40 }
    41 
    42 void print(int x, int y, int k){
    43     if(k==1)printf("%d", path[x][y][k]);
    44     else{
    45         print(x, path[x][y][k-1], k-1);
    46         printf(" %d", y);
    47     }
    48 }
    49 
    50 int main()
    51 {
    52 //    freopen("in.txt", "r", stdin);
    53 
    54     while(scanf("%d", &n)!=EOF){
    55         for(int i=1; i<=n; i++){
    56             for(int j=1; j<=n; j++){
    57                 if(i==j){Map[i][j] = 0;continue;}
    58                 scanf("%lf", &Map[i][j]);
    59             }
    60         }
    61         floyd();
    62         int f = 0, pos;
    63         for(int k=1; k<=n; k++){
    64             for(int i=1; i<=n; i++){
    65                 if(dis[i][i][k] >= 1.01){
    66                     f = 1;pos = i;break;
    67                 }
    68             }
    69             if(f){
    70                 print(pos, pos, k+1);
    71                 printf("
    ");
    72                 break;
    73             }
    74         }
    75         if(f==0)printf("no arbitrage sequence exists
    ");
    76     }
    77     return 0;
    78 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    Android研究之游戏开发处理按键的响应
    C语言指针的初始化和赋值
    Cloudera CDH 5集群搭建(yum 方式)
    未将对象引用设置到对象的实例--可能出现的问题总结
    内存泄漏以及常见的解决方法
    都能看懂的嵌入式linux/android alsa_aplay alsa_amixer命令行使用方法
    Life is hard!
    EasyUI基础入门之Resiable(可缩放)
    Android -- Looper.prepare()和Looper.loop() —深入版
    vi 命令 使用方法
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3466738.html
Copyright © 2011-2022 走看看