HDU 4784 Dinner Coming Soon DP

来源:互联网 发布:mac导入照片如何删除 编辑:程序博客网 时间:2024/05/21 08:58

题意: 在k个平行空间中,n个点,由m条有向边连接起来,每条边有一个时间花费和金钱花费,同时,在每个点上,可以跳转到(ki+1)%k 的空间里,不同空间的边权值不变。另外,在每到达某个空间的某个顶点时,可以买一包盐,卖一包盐,或者什么也不做,买卖的时间不考虑。相同的顶点在不同的空间中盐的价格也不一定相同..现在给定顶点数n,边数m,盐的最大携带量b,空间数k,初始的金钱r,规定的时间t,问怎么走可以在t时间内从1到达n,并且使到达n时身上的金钱尽可能大。初始时身上一包盐也没有,并且只有在空间0的时候,才能访问顶点1和n,并且一旦到达顶点n,这个过程就要结束......


dp[i][j][k][l]: i时刻在j宇宙k城市有l包盐最多能

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#define pb push_back#define mp make_pair#define fi first#define se second#define pii pair<int,int>#define LL long longusing namespace std;const int MAXN = 210;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const double eps = 1e-10;int dp[MAXN][10][MAXN][10];int price[10][MAXN];vector<pair<int,pii > > g[MAXN];int main(){    freopen("test.txt","r",stdin);    int T;scanf("%d",&T);    for(int cas = 1;cas <= T;cas++){        int N,M,B,K,R,T;        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",&price[i][j]);        for(int i = 0; i <= N;i++) g[i].clear();        for(int i = 0; i < M;i++){            int u,v,t,c;            scanf("%d%d%d%d",&u,&v,&t,&c);            g[u].pb(mp(v,mp(t,c)));        }        memset(dp,-1,sizeof(dp));        dp[0][0][1][0] = R;        for(int t = 0; t < T; t++)            for(int kind = 0; kind < K;kind++)                for(int u = 1; u < N; u++){                    if((u == 1 || u == N) && kind != 0) continue;                    for(int salt = 0;salt <= B;salt++){                        if(dp[t][kind][u][salt] < 0) continue;                        if(u != 1 && u != N){                            for(int d = -1; d <= 1;d++){                                int cc = price[kind][u] * d;                                if(salt + d >= 0 && salt + d <= B && dp[t][kind][u][salt] >= cc){                                    dp[t+1][(kind + 1) % K][u][salt + d] = max(dp[t][kind][u][salt] - cc,dp[t+1][(kind + 1) % K][u][salt + d]);                       //             cout<<t + 1<<' '<<(kind + 1) % K<<' '<<u<<' '<<salt + d<<' '<<dp[t+1][(kind + 1) % K][u][salt + d]<<endl;                                }                            }                        }                        for(int i = 0; i < g[u].size();i++){                            int v = g[u][i].fi;                            if(kind != 0 && (v == 1 || v == N)) continue;                            int w = g[u][i].se.fi;                            int c = g[u][i].se.se;                            int tt = t + w;                            if(tt > T) continue;                            if(u != 1 && u != N){                                for(int d = -1; d <= 1;d++){                                    int cc = c + price[kind][u] * d;                                    if(salt + d >= 0 && salt + d <= B && dp[t][kind][u][salt] >= cc)                                        dp[tt][kind][v][salt + d] = max(dp[tt][kind][v][salt + d],dp[t][kind][u][salt] - cc);                       //             cout<<tt<<' '<<kind<<' '<<v<<' '<<salt + d<<' '<<dp[tt][kind][v][salt + d]<<endl;                                }                            }                            else if(dp[t][kind][u][salt] >= c){                                dp[tt][kind][v][salt] = max(dp[tt][kind][v][salt],dp[t][kind][u][salt] - c);                     //           cout<<tt<<' '<<kind<<' '<<v<<' '<<salt<<' '<<dp[tt][kind][v][salt]<<endl;                            }                        }                    }                }        int res = -1;        for(int i = 1; i <= T;i++)            res = max(res,dp[i][0][N][0]);        if(res < 0) printf("Case #%d: Forever Alone\n",cas);        else printf("Case #%d: %d\n",cas,res);    }    return 0;}

有多少钱

原创粉丝点击