hdu 4784 Dinner Coming Soon dp

不算很难的一个dp,一个错误的认识是只有DAG才能dp,当然只有DAG才能dp,但是这里的图有环,它却是DAG,因为有了其它维度(比如时间),那么不同时间的同一个点其实是两个不同的点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int N,M,B,K,R,T;
int p[12][120];/// p[k][i],kth层第i个点
int u,v,t,m;
struct Edge
{
    int v,t,m;
};
vector<Edge> G[maxn];
int dp[120][12][210][6][3];/// dp[i][k][t][b][op] , 0 nothing,1 sell,2 buy
bool vis[120][12][210][6][3];

void Input()
{
    REP(i,1,N) G[i].clear();
    REP(k,0,K-1){
        REP(i,1,N){
            scanf("%d",&p[k][i]);
        }
    }
    REP(i,1,M){
        scanf("%d%d%d%d",&u,&v,&t,&m);
        G[u].push_back({v,t,m});
    }
}

int dfs(int u,int k,int t,int b,int op)
{
    if(t<0||b>B||b<0) return -INF;
    int &res=dp[u][k][t][b][op];
    if(vis[u][k][t][b][op]) return res;
    vis[u][k][t][b][op]=1;
    if(u==1||u==N) if(k||op) return res=-INF;
    if(u==N) return res=0;
    res=-INF;
    int tmp;
    /// 到这一层的其它点
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i].v,wt=G[u][i].t,wn=G[u][i].m;
        tmp=dfs(v,k,t-wt,b,0)-wn;
        if(tmp>=-R) res=max(res,tmp);
        tmp=dfs(v,k,t-wt,b-1,1)-wn+p[k][v];
        if(tmp>=-R) res=max(res,tmp);
        tmp=dfs(v,k,t-wt,b+1,2)-wn-p[k][v];
        if(tmp>=-R) res=max(res,tmp);
    }
    /// 到下一层
    int nk=(k+1)%K;
    //cout<<"u="<<u<<" k="<<k<<" nk="<<nk<<endl;
    tmp=dfs(u,nk,t-1,b,0);
    if(tmp>=-R) res=max(res,tmp);
    tmp=dfs(u,nk,t-1,b-1,1)+p[nk][u];
    if(tmp>=-R) res=max(res,tmp);
    tmp=dfs(u,nk,t-1,b+1,2)-p[nk][u];
    if(tmp>=-R) res=max(res,tmp);
    return res;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int cas;cin>>cas;int casen=1;
    while(cas--){
        scanf("%d%d%d%d%d%d",&N,&M,&B,&K,&R,&T);
        Input();
        MS0(vis);MS0(dp);
        printf("Case #%d: ",casen++);
        //cout<<"T="<<T<<" B="<<B<<endl;
        //cout<<"=="<<dfs(2,0,T,0,0)<<endl;
        //cout<<"==="<<dfs(2,1,T,B,1)<<endl;
        int ans=R+dfs(1,0,T,0,0);
        //cout<<"R="<<R<<endl;
        //cout<<R<<" "<<dfs(1,0,T,B,0)<<endl;
        if(ans<0) puts("Forever Alone");
        else printf("%d\n",ans);
    }
    return 0;
}
/**
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
*/
View Code

第一次提交WA的时候我以为我会调试很久,没想到检查了一遍之后很快发现了有一个字符打错,改了一下,在测了一下其它数据,再把思路从头到尾理一下,顺便再检查一下代码,提交,出现了令人兴奋的Accepted!之前老是出现满屏的WA,这次这么快就出现Accept,很久没有令人兴奋的这种感觉了。改变了做题习惯后,我的状态慢慢找回来了。下一场codeforces我要涨分!

posted @ 2016-03-09 19:39  __560  阅读(235)  评论(0编辑  收藏  举报