Hdu 4571 Travel in time(dp)

题目链接

Travel in time

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1898    Accepted Submission(s): 383


Problem Description
  Bob gets tired of playing games, leaves Alice, and travels to Changsha alone. Yuelu Mountain, Orange Island, Window of the World, the Provincial Museum etc...are scenic spots Bob wants to visit. However, his time is very limited, he can’t visit them all.
  Assuming that there are N scenic spots in Changsha, Bob defines a satisfaction value Si to each spot. If he visits this spot, his total satisfaction value will plus Si. Bob hopes that within the limited time T, he can start at spot S, visit some spots selectively, and finally stop at spot E, so that the total satisfaction value can be as large as possible. It's obvious that visiting the spot will also cost some time, suppose that it takes C i units of time to visit spot i ( 0 <= i < N ).
  Always remember, Bob can choose to pass by a spot without visiting it (including S and E), maybe he just want to walk shorter distance for saving time.
  Bob also has a special need which is that he will only visit the spot whose satisfaction value is strictly larger than that of which he visited last time. For example, if he has visited a spot whose satisfaction value is 50, he would only visit spot whose satisfaction value is 51 or more then. The paths between the spots are bi-directional, of course.
 

Input
  The first line is an integer W, which is the number of testing cases, and the W sets of data are following.
  The first line of each test data contains five integers: N M T S E. N represents the number of spots, 1 < N < 100; M represents the number of paths, 0 < M < 1000; T represents the time limitation, 0 < T <= 300; S means the spot Bob starts from. E indicates the end spot. (0 <= S, E < N)
  The second line of the test data contains N integers C i ( 0 <= C i <= T ), which means the cost of time if Bob visits the spot i.
  The third line also has N integers, which means the satisfaction value Si that can be obtained by visiting the spot i ( 0 <= S i < 100 ).
  The next M lines, each line contains three integers u v L, means there is a bi-directional path between spot u and v and it takes L units of time to walk from u to v or from v to u. (0 <= u, v < N, 0 <= L <= T)
 

Output
  Output case number in the first line (formatted as the sample output).
  The second line contains an integer, which is the greatest satisfaction value.
If Bob can’t reach spot E in T units of time, you should output just a “0” (without quotation marks).
 

Sample Input
  
  
1 4 4 22 0 3 1 1 1 1 5 7 9 12 0 1 10 1 3 10 0 2 10 2 3 10
 

Sample Output
  
  
Case #1: 21

题意:N个点M条边的有向图,要在T的时间范围内从S走到E。对于一个点 i ,我们还可以花Ci的时间在i 点游玩,可以获得val[ i ] 的价值,建设我们在这个点游玩了,那么我们下一个游玩的点的val值必须大于val[i] 。求在规定时间内从S走到E能获得的最大价值。

题解:首先用floyd处理出点到点的最短距离。由于我们已经处理出点到点的最短距离,所以我们去访问一个点一定是要到那个点游玩,因此我们可以用dp[i][j] ,表示在第 i 个点,第i个点已经游玩了,从起点到现在已经花了时间j ,在这个状态下能获得的最大价值。这个dp的写法有很多,我是用优先队列+bfs写的。代码如下:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<math.h>
#include<string>
#include<set>
#include<map>
#define nn 610000
#define inff 0x3fffffff
using namespace std;
typedef __int64 LL;
typedef unsigned __int64 ULL;
int n,m,s,e,T;
int c[110];
int val[110];
int tu[110][110];
int dp[110][310];
struct node
{
    int id,ti;
    node(){}
    node(int x,int y)
    {
        id=x,ti=y;
    }
    friend bool operator<(node aa,node bb)
    {
        if(aa.ti==bb.ti)
            return val[aa.id]>val[bb.id];
        return aa.ti>bb.ti;
    }
};
priority_queue<node>que;
bool inque[110][310];
int solve()
{
    int i,j;
    c[n]=0,val[n]=-1;
    for(i=0;i<=n;i++)
    {
        for(j=0;j<=T;j++)
        {
            dp[i][j]=-inff;
            inque[i][j]=false;
        }
    }
    int re=0;
    dp[n][0]=0;
    que.push(node(n,0));
    inque[n][0]=true;
    node sta;
    int ti;
    while(que.size())
    {
        sta=que.top();
        que.pop();
        //inque[sta.id][sta.ti]=false;
        if(sta.id==e)
        {
            re=max(re,dp[sta.id][sta.ti]);
        }
        for(i=0;i<n;i++)
        {
            if(sta.ti+tu[sta.id][i]+c[i]<=T&&val[i]>val[sta.id])
            {
                ti=sta.ti+tu[sta.id][i]+c[i];
                if(dp[i][ti]<dp[sta.id][sta.ti]+val[i])
                {
                    dp[i][ti]=dp[sta.id][sta.ti]+val[i];
                    if(!inque[i][ti])
                    {
                        inque[i][ti]=true;
                        que.push(node(i,ti));
                    }
                }
            }
        }
    }
    for(i=0;i<=n;i++)
    {
        for(j=0;j<=T;j++)
        {
            if(j+tu[i][e]<=T)
                re=max(re,dp[i][j]);
        }
    }
    return re;
}
int main()
{
    int t,i,j,k;
    int u,v,l;
    int cas=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d%d",&n,&m,&T,&s,&e);
        for(i=0;i<n;i++)
        {
            scanf("%d",&c[i]);
        }
        for(i=0;i<n;i++)
        {
            scanf("%d",&val[i]);
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                tu[i][j]=i==j?0:inff;
            }
        }
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&l);
            tu[u][v]=min(tu[u][v],l);
            tu[v][u]=min(tu[v][u],l);
        }
        for(k=0;k<n;k++)
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                {
                    tu[i][j]=min(tu[i][j],tu[i][k]+tu[k][j]);
                }
            }
        }
        for(i=0;i<n;i++)
        {
            tu[n][i]=tu[s][i];
            tu[i][n]=tu[i][s];
        }
        printf("Case #%d:\n",cas++);
        printf("%d\n",solve());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值