hdu 4517 floyd+记忆化搜索

来源:互联网 发布:安卓录屏内录声音软件 编辑:程序博客网 时间:2024/06/10 03:38

题意:

有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。

访问每个景点需要时间cost_i,每个景点的访问价值为value_i。

点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。

走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。

现在求,从起点出发,到达终点,在时间限制内,能得到的最大价值为多少。

如果不能从s到达e,则输出0。


解析:

首先应该走到一个点可以选择访问或者不访问,所以可以用floyd求出点与点之间最近的距离为多少。

然后dp[ i ] [ j ] [ k ] 表示的是,当前走到 i 点,前一个点的价值为 j ,并且还有剩余时间 k 的最大价值。

详见代码。


代码:

#pragma comment(linker, "/STACK:1677721600")#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <climits>#include <cassert>#include <iostream>#include <algorithm>#define pb push_back#define mp make_pair#define LL long long#define lson lo,mi,rt<<1#define rson mi+1,hi,rt<<1|1#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define mem(a,b) memset(a,b,sizeof(a))#define FIN freopen("in.txt", "r", stdin)#define FOUT freopen("out.txt", "w", stdout)#define rep(i,a,b) for(int i=(a); i<=(b); i++)#define dec(i,a,b) for(int i=(a); i>=(b); i--)using namespace std;const int mod = 1e9 + 7;const double eps = 1e-8;const double ee = exp(1.0);const int inf = 0x3f3f3f3f;const int maxn = 100 + 10;const int maxt = 300 + 10;const double pi = acos(-1.0);const LL iinf = 0x3f3f3f3f3f3f3f3f;int readT(){    char c;    int ret = 0,flg = 0;    while(c = getchar(), (c < '0' || c > '9') && c != '-');    if(c == '-') flg = 1;    else ret = c ^ 48;    while( c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c ^ 48);    return flg ? - ret : ret;}int n, m, t, s, e;int g[maxn][maxn];int dp[maxn][maxn][maxt];int cost[maxn];int value[maxn];void floyd(){    rep(i, 0, n - 1)    {        g[i][i] = 0;    }    rep(k, 0, n - 1)    {        rep(i, 0, n - 1)        {            rep(j, 0, n - 1)            {                g[i][j] = Min(g[i][j], g[i][k] + g[k][j]);            }        }    }}int dfs(int u, int preVal, int timeLeft){    if (g[u][e] > timeLeft)        return -inf;    int& res = dp[u][preVal][timeLeft];    if (res != -1)        return res;    res = 0;    rep(i, 0, n - 1)    {        if (preVal < value[i])        {            res = Max(res, dfs(i, value[i], timeLeft - g[u][i] - cost[i]) + value[i]);        }    }    return res;}int main(){#ifdef LOCAL    FIN;#endif // LOCAL    int ncase = readT();    int ca = 1;    while (ncase--)    {        scanf("%d%d%d%d%d", &n, &m, &t, &s, &e);        mem(dp, -1);        mem(g, inf);        rep(i, 0, n - 1)        {            cost[i] = readT();        }        rep(i, 0, n - 1)        {            value[i] = readT();        }        rep(i, 0, m - 1)        {            int u = readT();            int v = readT();            int w = readT();            g[u][v] = g[v][u] = Min(g[u][v], w);        }        floyd();        int ans = dfs(s, 0, t);        printf("Case #%d:\n", ca++);        printf("%d\n", ans == -inf ? 0 : ans);    }    return 0;}


0 0