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

  • 相关阅读:
    MySQL与OLAP:分析型SQL查询最佳实践探索
    创建与删除索引
    第三方推送-个推使用
    test
    图床_搭建本地yum仓库及自制rpm包(无需镜像)
    图床_有趣的linux命令行工具-lolcat
    图床_fdisk一键操作分区-无需脚本
    图床_将你的CentOS 7 配置yum源
    图床_使用Putty远程连接管理Linux实践
    图床_使用Xshell远程连接管理Linux实践
  • 原文地址:https://www.cnblogs.com/Griselda/p/2687188.html
Copyright © 2011-2022 走看看