2013长沙邀请赛Travel in time

来源:互联网 发布:中山大学网络在线缴费 编辑:程序博客网 时间:2024/04/29 04:37

题意:给一个无向图和时间限制,景点到景点需要时间,每游览一个景点会得到相应价值也会花费相应时间,而且你下一个游览的景点的价值必须比现在的大。求从起始景点到结束景点获得的最大价值。你可以路过任意一个景点而不游览,这样也不花费时间。


首先,肯定要求出景点间的最短距离,因为任意景点都可以只路过,所以增加一个虚拟起点,这里景点编号0~n-1,所以虚拟起点定为n。初始化:cost【n】【be】=cost【be】【n】=0(be为起始景点),然后Floyd、Spfa什么的求最短路径。


其次,最大价值需要dp求解:

前提条件:val[i]>val[t]&&sum+cost[t][i]+need[i]+cost[i][en]<=lim
关系方程:dp[sum][t]=max(dp[sum][t],deal(sum+cost[t][i]+need[i],i)+val[i]);
其中sum为当前花费时间,t为此时游览的景点,lim为时间限制,val数组为景点价值,cost数组为最短路径花费时间,need数组为游览这个景点花费时间。(i从0~n-1)
#include<cstdio>#include<algorithm>using namespace std;int n,lim,en;int need[305],val[305];int cost[305][305],dp[305][305];int deal(int sum,int t){    if(dp[sum][t]!=-1)return dp[sum][t];    dp[sum][t]=0;    for(int i=0; i<n; i++)        if(val[i]>val[t]&&sum+cost[t][i]+need[i]+cost[i][en]<=lim)            dp[sum][t]=max(dp[sum][t],deal(sum+cost[t][i]+need[i],i)+val[i]);    return dp[sum][t];}int main(){    int T,t,m,be,i,j,k;    scanf("%d",&T);    for(t=1; t<=T; t++)    {        memset(dp,-1,sizeof(dp));        scanf("%d%d%d%d%d",&n,&m,&lim,&be,&en);        for(i=0; i<n; i++)            scanf("%d",&need[i]);        for(i=0; i<n; i++)            scanf("%d",&val[i]);        for(i=0; i<=n; i++)        {            for(j=0; j<=n; j++)                cost[i][j]=12345678;            cost[i][i]=0;        }        cost[n][be]=cost[be][n]=0;        for(i=0; i<m; i++)        {            int u,v,c;            scanf("%d%d%d",&u,&v,&c);            if(cost[u][v]>c)cost[u][v]=cost[v][u]=c;        }        for(k=0; k<=n; k++)            for(i=0; i<=n; i++)                for(j=0; j<=n; j++)                    if(cost[i][j]>cost[i][k]+cost[k][j])cost[i][j]=cost[i][k]+cost[k][j];        printf("Case #%d:\n",t);        if(cost[n][en]>lim)printf("0\n");        else printf("%d\n",deal(0,n));    }    return 0;}/*34 4 22 0 31 1 1 15 7 9 120 1 101 3 100 2 102 3 1021*/

0 0