zoukankan      html  css  js  c++  java
  • Hdu 4284 状态DP 能否走完所选城市.cpp

    题意:

    已知s.b原来有多少钱 in

    以及知道 m 个去他想去的城市工作需要用多少钱以及能挣到多少钱  

    然后知道他从 a 城市到 b 城市得花多少钱..  

    问他能不能去完他想去的城市??

    给出一个 T 表示样例个数

    接下来每个样例给出一个 n m in

    表示有 n 个点 m 个想去的地方

    接下来 m 行..每行给出 a b w 代表 a 城市和 b 城市之间路费为 w

    然后有一个 h 表示他想去的城市个数

    接下来 h 行..给出 a c d 代表在a城市需要花d元 能够挣 c 元

    思路:

    状态压缩DP..

    求出城市间最短距离

    初始状态是如果从第一个城市到第 i 个城市的路费+花费 >= 0 就让这个dp[ 1<< i ][ i ]的值更新为 剩下的钱+挣的钱

    然后枚举所有的状态

    枚举所有的可能性..找出按某个顺序能挣得的钱越多的..

    然后如果最后所有方案中有一个的钱的总数 >= 0就代表他可以走遍他想去的城市..

    Tips:

     因为可能出现重边 所以要加判断语句

     dis的初始化对dis[ i ][ i ] = 0;

    Code:

    View Code
     1 #include <stdio.h>
     2 #include <cstring>
     3 using namespace std;
     4 #define clr(x) memset(x, 0, sizeof(x))
     5 const int INF = 0x1f1f1f1f;
     6 #define max(a, b) ((a) > (b)?(a):(b))
     7 
     8 int T, n, m, h, a, b, c, d, w, in;
     9 int dis[110][110], dp[1<<15][15];
    10 bool flag;
    11 
    12 struct CD
    13 {
    14     int num;
    15     int c;
    16     int d;
    17 }cd[15];
    18 
    19 void floyd()
    20 {
    21     for(int k = 1; k <= n; ++k)
    22     for(int i = 1; i <= n; ++i)
    23     for(int j = 1; j <= n; ++j) {
    24         dis[i][j] = dis[i][j]<dis[i][k]+dis[k][j]?dis[i][j]:dis[i][k]+dis[k][j];
    25     }
    26 }
    27 
    28 void solve()
    29 {
    30     int i, j, k;
    31     int tmp, st, stat;
    32 
    33     st = (1<<h)-1;
    34     memset(dp, 0xff, sizeof(dp));
    35 
    36     floyd();
    37     for(i = 0; i < h; ++i) {
    38         tmp = in-dis[1][cd[i].num]-cd[i].d;
    39         if(tmp >= 0) {
    40             dp[1<<i][i] = tmp+cd[i].c;
    41         }
    42     }
    43 
    44     for(i = 1; i <= st; ++i)
    45     for(j = 0; j < h; ++j)
    46     if(dp[i][j] >= 0) {
    47         for(k = 0; k < h; ++k)
    48         if(!(i&(1<<k))) {
    49             tmp = dp[i][j] - dis[cd[j].num][cd[k].num] - cd[k].d;
    50             if(tmp >= 0) {
    51                 stat = i+(1<<k);
    52                 dp[stat][k] = max(dp[stat][k], tmp+cd[k].c);
    53             }
    54         }
    55     }
    56 
    57     for(i = 0; i < h; ++i) {
    58         tmp = dp[st][i]-dis[cd[i].num][1];
    59         if(tmp >= 0) {
    60             flag = true;
    61             break;
    62         }
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     int i, j, k;
    69     while(scanf("%d", &T) != EOF)
    70     while(T--)
    71     {
    72         memset(dis, INF, sizeof(dis));
    73         flag = false;
    74         for(i = 1; i <= n; ++i)
    75             dis[i][i] = 0;
    76 
    77         scanf("%d %d %d", &n, &m, &in);
    78         while(m--) {
    79             scanf("%d %d %d", &a, &b, &w);
    80             if(w < dis[a][b])
    81             dis[a][b] = dis[b][a] = w;
    82         }
    83         scanf("%d", &h);
    84         for(i = 0; i < h; ++i)
    85             scanf("%d %d %d", &cd[i].num, &cd[i].c, &cd[i].d);
    86 
    87         solve();
    88 
    89         if(flag) puts("YES");
    90         else puts("NO");
    91     }
    92     return 0;
    93 }

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4284

  • 相关阅读:
    BZOJ 3744 Gty的妹子序列
    BZOJ 3872 Ant colony
    BZOJ 1087 互不侵犯
    BZOJ 1070 修车
    BZOJ 2654 tree
    BZOJ 3243 向量内积
    1003 NOIP 模拟赛Day2 城市建设
    CF865D Buy Low Sell High
    CF444A DZY Loves Physics
    Luogu 4310 绝世好题
  • 原文地址:https://www.cnblogs.com/Griselda/p/2687188.html
Copyright © 2011-2022 走看看