HDU 4784 - Dinner Coming Soon(BFS)

来源:互联网 发布:亚瑟士跑鞋推荐 知乎 编辑:程序博客网 时间:2024/05/17 23:53

题目:

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

题意:

n个点m条边,从1出发,有钱数R,在T时间内到达终点n。且除了起点和终点起点有k个维度。起点和终点在0维上。

途中可以买卖盐,以使得钱数尽可能地多。途中的点有多个维度,只能从k维跳到(k+1)维,花费时间为1,在各维度上进行买卖不需要时间。

每条有向边有时间和花费。求出到达终点的最大资金。

思路:

首先要明确题意!!!在每一维的操作是买一个,卖一个,或者不做。

dp[u][k][b][t]: 表示u点在k维上有b袋盐已消耗时间t时 的最大资金。

使用优先队列储存状态,按照时间从小到大进行排序。对于当前点u的状态的操作有:转移到另一维度(买,卖,不干),移动到另一点(买,卖,不干)。

vis数组表示此种状态是否已经历过,没有的话放入队列。

AC.

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>using namespace std;const int inf = 0x3f3f3f3f;int N, M, B, K, R, T;int dp[105][10][10][250];int val[105][10];int tol, head[105];struct Edge{    int to, tim, w, nex;}edge[250];void init(){    tol = 0;    memset(head, -1, sizeof(head));}void addedge(int u, int v, int tim, int w){    edge[tol].to = v;    edge[tol].tim = tim;    edge[tol].w = w;    edge[tol].nex = head[u];    head[u] = tol++;}struct node{    int u, nok, nob, cnt;    bool operator < (const node & A) const {        return cnt > A.cnt;    }};bool vis[105][10][10][250];int bfs(){    memset(dp, -1, sizeof(dp));    memset(vis, 0, sizeof(vis));    priority_queue<node> que;    que.push((node){1, 0, 0, 0});    dp[1][0][0][0] = R;    vis[1][0][0][0] = 1;    int ans = -1;    while(!que.empty()) {        node now = que.top(); que.pop();        int u = now.u, nok = now.nok, nob = now.nob, ccnt = now.cnt;        int rr = dp[u][nok][nob][ccnt];        vis[u][nok][nob][ccnt] = 0;        if(u == N) continue;        if(ccnt > T) {            break;        }        //move other        for(int i = head[u]; ~i; i = edge[i].nex) {            int v = edge[i].to, t = edge[i].tim, w = edge[i].w;            int cnt = ccnt+t, r = rr-w;            if(cnt > T || r < 0) continue;            //do nothing            if(dp[v][nok][nob][cnt] < r) {                 dp[v][nok][nob][cnt] = r;                 if(!vis[v][nok][nob][cnt] ) {                    que.push((node){v, nok, nob, cnt});                    vis[v][nok][nob][cnt] = 1;                }            }            if(v == N || v == 1) continue;            //buy one            if(nob+1 <= B && dp[v][nok][nob+1][cnt] < r - val[v][nok]) {                dp[v][nok][nob+1][cnt] = r - val[v][nok];                if(!vis[v][nok][nob+1][cnt]) {                    que.push((node){v, nok, nob+1, cnt});                    vis[v][nok][nob+1][cnt] = 1;                }            }            //sell one            if(nob > 0 &&  dp[v][nok][nob-1][cnt] < r + val[v][nok]) {                dp[v][nok][nob-1][cnt] = r + val[v][nok];                if(!vis[v][nok][nob-1][cnt]) {                    que.push((node){v, nok, nob-1, cnt});                    vis[v][nok][nob-1][cnt] = 1;                }            }        }        int r = rr;        if(u != 1 && u != N) {            nok = (nok+1)%K;            int cnt = ccnt+1;            if(cnt > T) continue;            //buy one            if(nob+1 <= B && dp[u][nok][nob+1][cnt] < r - val[u][nok]) {                dp[u][nok][nob+1][cnt] = r - val[u][nok];                if(!vis[u][nok][nob+1][cnt]) {                    que.push((node){u, nok, nob+1, cnt});                    vis[u][nok][nob+1][cnt] = 1;                }            }            //sell one            if(nob > 0 &&  dp[u][nok][nob-1][cnt] < r + val[u][nok]) {                dp[u][nok][nob-1][cnt] = r + val[u][nok];                if(!vis[u][nok][nob-1][cnt]) {                    que.push((node){u, nok, nob-1, cnt});                    vis[u][nok][nob-1][cnt] = 1;                }            }            //do nothing            if(dp[u][nok][nob][cnt] < r) {                dp[u][nok][nob][cnt] = r;                if(!vis[u][nok][nob][cnt]) {                    que.push((node){u, nok, nob, cnt});                    vis[u][nok][nob][cnt] = 1;                }            }        }    }    for(int i = 0; i <= T; ++i) {        for(int j = 0; j <= B; ++j) {            ans = max(ans, dp[N][0][j][i]);        }    }    return ans;}int main(){    //freopen("in", "r", stdin);    int TT, ca = 1;    scanf("%d", &TT);    while(TT--) {        scanf("%d%d%d%d%d%d", &N, &M, &B, &K, &R, &T);        for(int i = 0; i < K; ++i) {            for(int j = 1; j <= N; ++j) {                scanf("%d", &val[j][i]);            }        }        init();        int u, v, t, w;        for(int i = 0; i < M; ++i) {            scanf("%d%d%d%d", &u, &v, &t, &w);            addedge(u, v, t, w);        }        printf("Case #%d: ", ca++);        int ans = bfs();        if(ans == -1) printf("Forever Alone\n");        else printf("%d\n", ans);    }    return 0;}



0 0
原创粉丝点击