题意: 在k个平行空间中,n个点,由m条有向边连接起来,每条边有一个时间花费和金钱花费,同时,在每个点上,可以跳转到(ki+1)%k 的空间里,不同空间的边权值不变。另外,在每到达某个空间的某个顶点时,可以买一包盐,卖一包盐,或者什么也不做,买卖的时间不考虑。相同的顶点在不同的空间中盐的价格也不一定相同..现在给定顶点数n,边数m,盐的最大携带量b,空间数k,初始的金钱r,规定的时间t,问怎么走可以在t时间内从1到达n,并且使到达n时身上的金钱尽可能大。初始时身上一包盐也没有,并且只有在空间0的时候,才能访问顶点1和n,并且一旦到达顶点n,这个过程就要结束......
dp[i][j][k][l]: i时刻在j宇宙k城市有l包盐最多能
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define LL long long
using namespace std;
const int MAXN = 210;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double eps = 1e-10;
int dp[MAXN][10][MAXN][10];
int price[10][MAXN];
vector<pair<int,pii > > g[MAXN];
int main()
{
freopen("test.txt","r",stdin);
int T;scanf("%d",&T);
for(int cas = 1;cas <= T;cas++){
int N,M,B,K,R,T;
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",&price[i][j]);
for(int i = 0; i <= N;i++) g[i].clear();
for(int i = 0; i < M;i++){
int u,v,t,c;
scanf("%d%d%d%d",&u,&v,&t,&c);
g[u].pb(mp(v,mp(t,c)));
}
memset(dp,-1,sizeof(dp));
dp[0][0][1][0] = R;
for(int t = 0; t < T; t++)
for(int kind = 0; kind < K;kind++)
for(int u = 1; u < N; u++){
if((u == 1 || u == N) && kind != 0) continue;
for(int salt = 0;salt <= B;salt++){
if(dp[t][kind][u][salt] < 0) continue;
if(u != 1 && u != N){
for(int d = -1; d <= 1;d++){
int cc = price[kind][u] * d;
if(salt + d >= 0 && salt + d <= B && dp[t][kind][u][salt] >= cc){
dp[t+1][(kind + 1) % K][u][salt + d] = max(dp[t][kind][u][salt] - cc,dp[t+1][(kind + 1) % K][u][salt + d]);
// cout<<t + 1<<' '<<(kind + 1) % K<<' '<<u<<' '<<salt + d<<' '<<dp[t+1][(kind + 1) % K][u][salt + d]<<endl;
}
}
}
for(int i = 0; i < g[u].size();i++){
int v = g[u][i].fi;
if(kind != 0 && (v == 1 || v == N)) continue;
int w = g[u][i].se.fi;
int c = g[u][i].se.se;
int tt = t + w;
if(tt > T) continue;
if(u != 1 && u != N){
for(int d = -1; d <= 1;d++){
int cc = c + price[kind][u] * d;
if(salt + d >= 0 && salt + d <= B && dp[t][kind][u][salt] >= cc)
dp[tt][kind][v][salt + d] = max(dp[tt][kind][v][salt + d],dp[t][kind][u][salt] - cc);
// cout<<tt<<' '<<kind<<' '<<v<<' '<<salt + d<<' '<<dp[tt][kind][v][salt + d]<<endl;
}
}
else if(dp[t][kind][u][salt] >= c){
dp[tt][kind][v][salt] = max(dp[tt][kind][v][salt],dp[t][kind][u][salt] - c);
// cout<<tt<<' '<<kind<<' '<<v<<' '<<salt<<' '<<dp[tt][kind][v][salt]<<endl;
}
}
}
}
int res = -1;
for(int i = 1; i <= T;i++)
res = max(res,dp[i][0][N][0]);
if(res < 0) printf("Case #%d: Forever Alone\n",cas);
else printf("Case #%d: %d\n",cas,res);
}
return 0;
}
有多少钱