题目链接
https://vjudge.net/problem/HDU-4784
题目大意
从 1 1 1号点走到 n n n号点,有 m m m条有向路径,每条路径需要花费时间和路费,初始有r元,在每个点可以选择买入 o r or or 卖出 商品 o r or or不做 商品最多携带 b b b个, 共有 [ 0 , k − 1 ] [0,k-1] [0,k−1]个空间,可以花费 1 1 1的时间穿越到 ( i + 1 ) (i+1)%k (i+1)号空间,不同空间的交易价格不同,路径相同。此人不能穿越到1号点和n号点的非 0 0 0号空间 ,问在T时间内到达n号点时最大的所持金钱是多少
题解思路
这题主要是想学一下写法,参考了别人的思路,代码写的很漂亮。
想法其实很简单,虽然循环多但是数据量很小。
d
p
[
i
]
[
j
]
[
k
]
[
l
]
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;
}