• HDU 4284 Travel (状态dp)


      今年天津赛区网络赛的一道题,比赛的时候跟强哥讨论了一下,他的思路很明确,然后就让他去写了。。。赛后偶翻了翻这个题。。。额,还不错的状态dp把。。。就是让我给写搓了。。。贡献n次wa。。。

      题目是给一下点之间的花费,构成一个图(图不是很大,最多100*100)。然后指定一些必须访问的点。并且这些点上有一个先花费Di再收入Ci的过程,问能否实现访问所有这些点。。。

    因为指定的点数最多为15,加上1号点最多才17,所以直接用状态压缩就可以。先用floyd找出任意两点间的最小花费。然后dp[status][pos]表示当前状态为status并且最后访问的点为pos时,所有的资金数。最后找一个dp[(1<<h)-1][i] - dis[p[i].num][p[start].num] >= 0的点,如果存在则是YES,否则是NO

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    #define iabs(x) (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define lowbit(x)   i&(-i)
    
    const int eps = 1e-8;
    typedef long long LL;
    const int inf = ~0u>>2;
    
    using namespace std;
    
    const int N = 110;
    const int M = (1<<16) + 10;
    
    int dis[N][N];
    int dp[M][20];
    int n, m, my, h, st;
    
    struct node {
        int i;
        int c;
        int d;
        node() {}
        node(int x, int y, int z) : i(x), c(y), d(z) {}
        bool operator < (const node cmp) const {
            return i < cmp.i;
        }
    }p[20];
    
    void init() {
        int i, j;
        for(i = 1; i<= n; ++i) {
            for(j = 1; j <= n; ++j)
                dis[i][j] = (i == j) ? 0 : inf;
        }
    }
    
    void floyd() {
        int i, j, k;
        for(k = 1; k <= n; ++k) {
            for(i = 1; i <= n; ++i) {
                for(j = 1; j <= n; ++j)
                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
            }
        }
    }
    
    bool solve() {
        int status, i, j;
        CL(dp, -1);
        for(i = 0; i < h; ++i) {    //初始化
            if(my - dis[p[i].i][p[st].i] - p[i].d >= 0)
                dp[1<<i][i] = my - dis[p[i].i][p[st].i] - p[i].d + p[i].c;
        }
        for(status = 0; status < (1<<h); ++status) {
            for(i = 0; i < h; ++i) {
                if(dp[status][i] == -1) continue;
                for(j = 0; j < h; ++j) {
                    if(status&(1<<j))   continue;
                    if(dp[status][i] - dis[p[i].i][p[j].i] - p[j].d >= 0) {
                        dp[status|(1<<j)][j] = max(dp[status|(1<<j)][j], dp[status][i] - dis[p[i].i][p[j].i] - p[j].d + p[j].c);
                    }
                }
            }
        }
        for(i = 0; i < h; ++i) {
            if(dp[(1<<h)-1][i] - dis[p[i].i][p[st].i] >= 0)  break;
        }
        if(i >= h)  return false;
        return true;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int T, x, y, z, i;
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d%d", &n, &m, &my);
            init();
            while(m--) {
                scanf("%d%d%d", &x, &y, &z);
                if(z < dis[x][y]) {
                    dis[x][y] = dis[y][x] = z;
                }
            }
            floyd();
            scanf("%d", &h);
            st = -1;    //st表示初始点1的下标
            for(i = 0; i < h; ++i) {
                scanf("%d%d%d", &p[i].i, &p[i].c, &p[i].d);
                if(p[i].i == 1) st = i;
            }
            if(st == -1) {
                p[h] = node(1, 0, 0);    //如果没有再加进去。
                st = h++;
            }
            if(solve()) puts("YES");
            else    puts("NO");
        }
        return 0;
    }
  • 相关阅读:
    Python Module_openpyxl_styles 样式处理
    Python Module_openpyxl_styles 样式处理
    Microsoft Azure_Fabric
    Keepalived概述和安装(1)
    LVS集群TUN模式实例(5)
    LVS集群DR模式实例(4)
    LVS集群之NAT模式实例(3)
    LVS集群之工作原理和调度算法(2)
    HDFS基于路由的Federation方案
    HDFS基于路由的Federation方案
  • 原文地址:https://www.cnblogs.com/vongang/p/2680848.html
Copyright © 2020-2023  润新知