• hdu 4284 Travel (floyd + 状态 dp 2012 ACM/ICPC Asia Regional Tianjin Online )


    http://acm.hdu.edu.cn/showproblem.php?pid=4284

    题意:

    题目:给出一些城市,从1出发,旅游一圈回到1,由于花费可能不够,所以选择一些城市打工,打工之前需要花费d买一个证,工资为c。选中的城市必须去工作一次,而且只能工作一次,问能不能完成旅行

    这道 题 比赛是想的是  先 floyd  在 暴搜 ,结果 tle  赛后 看到  有人 暴搜 过了 ,,,,好无语(自己 考虑的 情况太多了)。。。。。。

    题解:

    首先 因为 我们 要用到的 只有 H 个点,所以我们先用 floyd 处理一下 ,构建一个 新图 ,在新图上处理,枚举 所有状态

    首先 暴搜 的 时间复杂度为 O(15 !),要超啊,状态压缩  O(H * H * 2^H);可以接受 ;

    dp[sta][i] 表示  状态  sta  最后一个工作的 节点 为 i   所剩的 最多钱数

     

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<string>
     11 #define Min(a,b) a<b?a:b
     12 #define Max(a,b) a>b?a:b
     13 #define CL(a,num) memset(a,num,sizeof(a));
     14 #define eps  1e-12
     15 #define inf 100000
     16 
     17 //freopen("data.txt","r",stdin);
     18 const double pi  = acos(-1.0);
     19 typedef   __int64  ll;
     20 using namespace std;
     21 int H,n,m,mon,sta,st;
     22 int dp[1 << 17][20] ,mat[maxn][maxn],a[20];
     23 struct node
     24 {
     25     int ci;
     26     int di ;
     27 }p[maxn] ;
     28 void floyd()
     29 {
     30     for(int k = 1;k<=n;k++)
     31     {
     32         for(int i = 1;  i <= n;i++ )
     33         {
     34             for(int  j = 1; j<= n;j++)
     35             {
     36                 if(mat[i][j] > mat[i][k] +  mat[k][j])
     37                 {
     38                     mat[i][j] = mat[i][k] + mat[k][j] ;
     39                 }
     40             }
     41         }
     42     }
     43 
     44 }
     45 void solve()
     46 {
     47      sta = 1 << H ;
     48     int  i,j,k;
     49     CL(dp,-1);
     50 
     51     for(i = 1;i<=H;i++)// 注意这 每一次 要 从  1 开始  出发,H 中 有没有 1  无所谓 
     52     {
     53         int tp = mon - mat[1][a[i]] - p[i].di ;
     54         if(tp >= 0)
     55          dp[1<<(i - 1)][i] = tp + p[i].ci ;
     56     }
     57 
     58     for(i = 0 ;i < sta;i++)
     59     {
     60         for(j = 1;j<=H;j++)
     61         {
     62             if(dp[i][j] < 0)continue ;
     63 
     64             int u = a[j] ;
     65 
     66             if(i & 1 <<(j - 1) == 0)continue ;
     67 
     68 
     69           for(k = 1;k<=H;k++)
     70           {
     71               int v = a[k];
     72               if(i & 1 << (k - 1))continue ;
     73 
     74               int t = i | 1 <<(k - 1) ;
     75 
     76               if(dp[i][j] >= mat[u][v] + p[k].di)
     77               {
     78                   if(dp[t][k] < dp[i][j] - mat[u][v] - p[k].di + p[k].ci);
     79                   dp[t][k] = dp[i][j] - mat[u][v] - p[k].di  + p[k].ci;
     80               }
     81 
     82 
     83           }
     84         }
     85     }
     86 }
     87 void init()
     88 {
     89     for(int i = 0 ; i <= n;i++)
     90     {
     91         for(int j = 0 ;j<= n;j++)
     92         {
     93            mat[i][j] =inf ;
     94             if(i == j)
     95             {
     96                  mat[i][j] = 0;
     97             }
     98         }
     99     }
    100 }
    101 int main()
    102 {
    103     //freopen("data.txt","r",stdin);
    104     int t,i,j,x,y,len;
    105     scanf("%d",&t);
    106     while(t--)
    107     {
    108         scanf("%d%d%d",&n,&m,&mon);
    109         init() ;
    110         for(i = 0 ;i< m;i++)
    111         {
    112             scanf("%d%d%d",&x,&y,&len);
    113             if(mat[x][y] > len)
    114             mat[x][y] = mat[y][x] = len ;
    115         }
    116         floyd() ;//在原图上 构建的新图
    117 
    118         scanf("%d",&H);
    119         int  f = 0;
    120         for(i = 1 ;i<= H;i ++ )
    121         {
    122             scanf("%d %d %d",&a[i],&p[i].ci,&p[i].di);
    123            
    124         }
    125 
    126 
    127        
    128         solve();
    129        int flag = 0;
    130 
    131         for(i = 1 ; i<= H;i++)
    132         {
    133             if(dp[sta - 1][i] >= mat[a[i]][1])
    134             {
    135 
    136                 flag = 1;
    137                 break ;
    138             }
    139         }
    140         if(flag)puts("YES");
    141         else puts("NO");
    142     }
    143 }
  • 相关阅读:
    ABAP中的‘多线程’
    SAP数据库表维护视图分配事务代码
    SAP调用外部数据库
    ABAP-小技巧/知识(1)
    sap中用函数增加断点(break point)
    把内表 itab1 的 n1 到 n2 行内容附加到 itab2 内表中去.
    ABAP打开TCODE
    查看用户下有那些事务码
    check、continue、exit的区别
    将excel数据导入内表的函数
  • 原文地址:https://www.cnblogs.com/acSzz/p/2682207.html
Copyright © 2020-2023  润新知