hdu 4784 Dinner Coming Soon bfs+dp

来源:互联网 发布:nasa气象数据下载 编辑:程序博客网 时间:2024/05/18 01:25

Dinner Coming Soon

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1349    Accepted Submission(s): 231


Problem Description
  Coach Pang loves his boyfriend Uncle Yang very much. Today is Uncle Yang’s birthday, Coach Pang wants to have a romantic candlelit dinner at Uncle Yang’s house and he has to arrive there in T minutes.
  There are N houses in their city numbered from 1 to N. Coach Pang lives in house 1 while Uncle Yang lives in house N. The houses are connected byM directed roads. It takes some time and usually a fee to pass one road. Coach Pang wants to reach Uncle Yang’s house before the dinner starts with as much money as possible.
  But the matter is not so simple. Coach Pang decides to do some salt trade on the way to Uncle Yang’s house. The host of each house offers a price of a bag of salt, so Coach Pang can make a profit from the price differences. Each time when Coach Pang arrives at a house (except the house 1 and the house N). He can buy one bag of salt, sell one bag of salt or do nothing. Coach Pang can carry at most B bags of salt with him, and he carries no salt when he leaves his house. The trading is so efficient that the time cost of trading can be ignored.
  However, the problem is more complicated than imagine. Coach Pang has a handheld device that can perform a journey around K parallel universes numbered from 0 to K-1. Coach Pang lives in the universe 0. When Coach Pang uses the device in universe i, he will be transported to the same place and the same time of universe (i+1) modK. The host of the house at the same place in different universe may offer a different price of salt. Luckily, the time cost and fee of the city roads are uniform among the K universes. The journey between universes costs no time but Coach Pang has to stand still watching the ads on the device for one minute every time before the device works. Remember, Coach Pang should never visit house 1 or house N in a universe other than universe 0, because the situation might become uncontrollable if he bumps into himself or his boyfriend in another universe.
  The time is running out. Coach Pang asks you to tell him whether he can arrive at Uncle Yang’s house in time, and how much money Coach Pang can have at most when the dinner starts. Coach Pang has R yuan at the start, and will end his journey immediately once he arrives at Uncle Yang’s house. He must arrive at Uncle Yang’s house in T minutes, and he can’t have negative amount of money anywhere anytime. Please help him!
 

Input
  The first line of the input is an integer C representing the number of test cases.
  For each test case, the first line will contain 6 integers N, M, B, K, R, T, as described above.
  (2 <= N <= 100, 0 <= M <= 200, 1 <= B <= 4, 2 <= K <= 5, 0 <= R <= 105, 0 <= T <= 200)
  The following K lines contain N integers each, indicating the price pij (0 <= i < K, 1 <= j <= N) for a bag of salt offered by the host of house j in the universe i. The price of house 1 and house N will be marked as -1.(1 <= pij <= 100)
  Then M lines follow, each contains 4 integers a, b, t and m, indicating that there is a road from house a to house b that costs t minutes of time and m yuan of money. (1 <= a,b <= N, a<> b, 1 <= t <=15, 0 <= m <= 100)
 

Output
  For each test case, output one line containing “Case #x: y”, where x is the case number (starting from 1) and y is the most money Coach Pang can have if he can have dinner with Uncle Yang on time.
  Print "Forever Alone" otherwise.
 

Sample Input
23 2 1 2 10 6-1 1 -1-1 5 -11 2 1 02 3 1 12 2 1 2 5 5-1 -1-1 -11 2 10 21 2 2 10
 

Sample Output
Case #1: 17Case #2: Forever Alone
 

Source
2013 Asia Chengdu Regional Contest
 

Recommend
We have carefully selected several similar problems for you:  5057 5056 5055 5054 5053 
 

出题人的思维我也是醉了,读+写绝对2个小时以上,比赛的时候有别的题就别优先考虑这种题。

题意:

有n个点,m条有向边,有一个人要在T时间内从1走到n,并在途中进行交易,获得尽量多的钱。这个人能带B包盐,除了1和n,每个点都有不同的盐价,所以可以根据差价赚钱。每条边有相应的时间和花费,到达一个点时有三个选择:买一包盐、卖一包盐、什么也不做,进行交易不需要时间。另外,还有K个平行世界(编号从0~K-1),每个是平行世界相应的盐价不同,但是相应道路的花费相同,这个人每次可以从第i个平行世界跳转到第(i+1)%K的平行世界(跳转前后位置相同),这个过程需要花费1分钟,但是他不能在1和n跳转,也就是说在1和n时必须是在第0个平行世界。当他到n的时候立即停止旅行,最后问能获得的最多的钱。

思路:

这题看着就像dp,思路也好想,开四维数组分别记录节点,空间,时间,盐,存的是当前状态最多的钱。然后广搜,按时间小顶堆,我用的vis标记每种情况是否走过,开的和dp一样的数组,注意1点和n点不能穿越也不能交易,然后就是考虑每种情况,到达每点分穿越和不穿越两种情况,每个情况有3种交易,一共是6种,尽情的写,尽情的debug吧,我用了2个多小时才调出来。。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>#include <vector>#include <queue>#include <map>using namespace std;const int N=105;const int inf=0x3f3f3f3f;struct node{    int v,next,ti,y;}edge[N];struct node2{    int id,t,k,b;    friend bool operator<(node2 a,node2 b){        return a.t>b.t;    }};int nume,b,r,t,n,m,k,u,v,ti,y,cas,icas=1;int dp[N][5][205][5],head[N],p[5][N];//节点,空间,时间,盐bool vis[N][5][205][5];priority_queue<node2> que;void addedge(int i,int j,int ti,int y){    edge[nume].v=j;    edge[nume].next=head[i];    edge[nume].ti=ti;    edge[nume].y=y;    head[i]=nume++;}void init(){    nume=1;    memset(head,-1,sizeof(head));    memset(dp,-inf,sizeof(dp));    memset(vis,0,sizeof(vis));    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",&p[i][j]);        }    }    for(int i=1;i<=m;i++){        scanf("%d%d%d%d",&u,&v,&ti,&y);        addedge(u,v,ti,y);    }    while(!que.empty())que.pop();}void bfs(){    dp[1][0][0][0]=r;    node2 tmp;    tmp.id=1;    tmp.k=0;    tmp.t=0;    tmp.b=0;    que.push(tmp);    while(!que.empty()){        tmp=que.top();        que.pop();        if(tmp.t>t)break;        if(tmp.id==n)continue;        if(tmp.id!=1){//穿越            int tk=tmp.k;            tmp.t++;            tmp.k=(tk+1)%k;            int yy=dp[tmp.id][tk][tmp.t-1][tmp.b];            dp[tmp.id][tmp.k][tmp.t][tmp.b]=max(dp[tmp.id][tmp.k][tmp.t][tmp.b],yy);            if(!vis[tmp.id][tmp.k][tmp.t][tmp.b]){                que.push(tmp);                vis[tmp.id][tmp.k][tmp.t][tmp.b]=1;            }            if(yy-p[tk][tmp.id]>=0&&tmp.b<b){//买                yy-=p[tk][tmp.id];                tmp.b++;                dp[tmp.id][tmp.k][tmp.t][tmp.b]=max(dp[tmp.id][tmp.k][tmp.t][tmp.b],yy);                if(!vis[tmp.id][tmp.k][tmp.t][tmp.b]){                    que.push(tmp);                    vis[tmp.id][tmp.k][tmp.t][tmp.b]=1;                }                tmp.b--;                yy+=p[tk][tmp.id];            }            if(tmp.b>0){//卖                yy+=p[tk][tmp.id];                tmp.b--;                dp[tmp.id][tmp.k][tmp.t][tmp.b]=max(dp[tmp.id][tmp.k][tmp.t][tmp.b],yy);                if(!vis[tmp.id][tmp.k][tmp.t][tmp.b]){                    que.push(tmp);                    vis[tmp.id][tmp.k][tmp.t][tmp.b]=1;                }                tmp.b++;                yy-=p[tk][tmp.id];            }            tmp.k=tk;            tmp.t--;        }        for(int i=head[tmp.id];i!=-1;i=edge[i].next){            int vt=edge[i].v;            node2 tmp2=tmp;            tmp2.id=vt;            tmp2.t+=edge[i].ti;            int yy=dp[tmp.id][tmp.k][tmp.t][tmp.b]-edge[i].y;            if(yy>=0){//不交易                dp[vt][tmp2.k][tmp2.t][tmp2.b]=max(dp[vt][tmp2.k][tmp2.t][tmp2.b],yy);                if(!vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]){                    que.push(tmp2);                    vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]=1;                }            }            if(yy-p[tmp2.k][tmp.id]>=0&&tmp2.b<b&&tmp.id!=1){//买                yy-=p[tmp2.k][tmp.id];                tmp2.b++;                dp[vt][tmp2.k][tmp2.t][tmp2.b]=max(dp[vt][tmp2.k][tmp2.t][tmp2.b],yy);                if(!vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]){                    que.push(tmp2);                    vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]=1;                }                tmp2.b--;                yy+=p[tmp2.k][tmp.id];            }            if(yy+p[tmp2.k][tmp.id]>=0&&tmp2.b>0&&tmp.id!=1&&tmp.id!=n){//卖                yy+=p[tmp2.k][tmp.id];                tmp2.b--;                dp[vt][tmp2.k][tmp2.t][tmp2.b]=max(dp[vt][tmp2.k][tmp2.t][tmp2.b],yy);                if(!vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]){                    que.push(tmp2);                    vis[tmp2.id][tmp2.k][tmp2.t][tmp2.b]=1;                }                tmp2.b++;                yy-=p[tmp2.k][tmp.id];            }        }    }    int ans=-inf;    for(int i=0;i<=t;i++){        for(int j=0;j<=b;j++){            ans=max(ans,dp[n][0][i][j]);        }    }    printf("Case #%d: ",icas++);    if(ans<0)printf("Forever Alone\n");    else printf("%d\n",ans);}int main(){    scanf("%d",&cas);    while(cas--){        init();        bfs();    }    return 0;}


0 0
原创粉丝点击