Gym 101617J
题意:
n个金矿,每一个金矿都有一个初始值代表第一天里面所含的金子数量,每天减少di,现在从金矿1出发,问最多能获得多少金子。
思路:
时间是最难解决的问题,因为时刻在变化,但是如果能够对时间做处理,那么题目就很简单了。
不妨枚举时间和前一个所在位置的状态,当时间和状态都满足的时候才可以继续走。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1005;
int n,m;
int dp[maxn][maxn];
struct Edge
{
int to,w;
};
vector<Edge>edge[maxn];
int v[maxn],d[maxn];
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i = 1;i <= n; i++) {
scanf("%d%d",&v[i],&d[i]);
}
for(int i = 1;i <= m; i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back(Edge{v,w});
edge[v].push_back(Edge{u,w});
}
memset(dp,-1,sizeof(dp));
dp[1][1] = v[1];
int ans = 0;
for(int i = 1;i <= 1000; i++) {
for(int j = 1;j <= n; j++) {
int Size = edge[j].size();
for(int k = 0;k < Size; k++) {
if(i-edge[j][k].w >= 1 && dp[i-edge[j][k].w][j] != -1) {
dp[i][edge[j][k].to] = max(dp[i][edge[j][k].to],dp[i-edge[j][k].w][j] + max(0,v[edge[j][k].to]-d[edge[j][k].to]*(i-1)));
}
if(dp[i][edge[j][k].to] != -1) ans = max(ans,dp[i][edge[j][k].to]);
}
}
}
printf("%d\n",ans);
return 0;
}