題目鏈接
https://vjudge.net/problem/HDU-4784
題目大意
從號點走到號點,有條有向路徑,每條路徑需要花費時間和路費,初始有r元,在每個點可以選擇買入 賣出 商品 不做 商品最多攜帶個, 共有個空間,可以花費的時間穿越到號空間,不同空間的交易價格不同,路徑相同。此人不能穿越到1號點和n號點的非號空間 ,問在T時間內到達n號點時最大的所持金錢是多少
題解思路
這題主要是想學一下寫法,參考了別人的思路,代碼寫的很漂亮。
想法其實很簡單,雖然循環多但是數據量很小。
在第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;
}