HDU - 4784 Dinner Coming Soon (dp)

題目鏈接

https://vjudge.net/problem/HDU-4784

題目大意

11號點走到nn號點,有mm條有向路徑,每條路徑需要花費時間和路費,初始有r元,在每個點可以選擇買入 oror 賣出 商品 oror不做 商品最多攜帶bb個, 共有[0,k1][0,k-1]個空間,可以花費11的時間穿越到(i+1)(i+1)%k號空間,不同空間的交易價格不同,路徑相同。此人不能穿越到1號點和n號點的非00號空間 ,問在T時間內到達n號點時最大的所持金錢是多少

題解思路

這題主要是想學一下寫法,參考了別人的思路,代碼寫的很漂亮。
想法其實很簡單,雖然循環多但是數據量很小。
dp[i][j][k][l]dp[i][j][k][l]在第i分鐘在j城 k維 攜帶l袋鹽所對應的最大價值
轉移的方向先考慮在當前點的三種方案(買 賣 不做)
再考慮下一個點,可以選擇穿越 或者 走起點爲該點轉移到下一個點。

貪心考慮 最優狀態一定在最後一個點的時候身上一袋鹽都不剩,枚舉一下時間取max就是答案

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
//#define int ll
#define debug cout<<"fuck"<<endl;
#define pb  push_back
#define endl '\n'
#define fi first
#define se second
#define db double
#define pii pair<int,int>
#define mp make_pair
const int mod=(int)1e9+7;
const int maxn=(int)105;
int add(int a, int b) {if((a += b) >= mod) a -= mod; return a < 0 ? a + mod : a;}
int mul(int a, int b) {return 1ll * a * b % mod;}

int t,n,m,b,d,r;
int dp[205][105][6][6];//在第i分鐘在j城 k維 攜帶l袋鹽所對應的最大價值
int p[6][maxn];


struct edge
{
    int to,tim,val;
};
vector<edge>v[maxn];

void trans(int i,int j,int k,int l,int val)
{
    for(auto edg:v[j])
    {
        if(val>=edg.val&&i+edg.tim<=t)
        {
            dp[i+edg.tim][edg.to][k][l]=max(dp[i+edg.tim][edg.to][k][l],val-edg.val);
        }
    }
    if(i+1<=t&&j!=1)
    dp[i+1][j][(k+1)%d][l]=max(dp[i+1][j][(k+1)%d][l],val);
}

void init()
{
    for(int i=0;i<maxn;i++)
    {
        v[i].clear();
    }
    memset(dp,-1,sizeof(dp));
}

int main()
{
    IOS
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        init();
        cin>>n>>m>>b>>d>>r>>t;
        //n個屋子 m條路 鹽的攜帶上限爲b 維度[0,d-1] 最初有r元 時間上限爲t
        for(int i=0;i<d;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>p[i][j];
            }
        }
        int x,y,minu,yuan;
        edge tem;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y>>minu>>yuan;
            tem.to=y;
            tem.tim=minu;
            tem.val=yuan;
            v[x].pb(tem);
        }
        dp[0][1][0][0]=r;
        for(int i=0;i<=t;i++)//時間
        {
            for(int j=1;j<n;j++)//城市
            {
                for(int k=0;k<d;k++)//維
                {
                    for(int l=0;l<=b;l++)//攜帶數
                    {
                        int valu=dp[i][j][k][l];
                        if(valu==-1)continue;
                        //買 賣 不做
                        if(j!=1&&l+1<=b&&valu>=p[k][j])
                            trans(i,j,k,l+1,valu-p[k][j]);

                        if(j!=1&&l)
                            trans(i,j,k,l-1,valu+p[k][j]);

                        trans(i,j,k,l,valu);
                    }
                }
            }
        }

        int ans=-1;
        for(int i=0;i<=t;i++)
        {
            ans=max(ans,dp[i][n][0][0]);
        }
        cout<<"Case #"<<kase<<": ";
        if(ans!=-1)cout<<ans<<endl;
        else cout<<"Forever Alone"<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章