hdu 4784 Dinner Coming Soon bfs+dp

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
2 3 2 1 2 10 6 -1 1 -1 -1 5 -1 1 2 1 0 2 3 1 1 2 2 1 2 5 5 -1 -1 -1 -1 1 2 10 2 1 2 2 10
 

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

Source
 

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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章