Treasure Map(Southeast USA ICPC 2017)
题意: 给你n个金矿,每个金矿初始有g[i]个,若当天不收集,当天采的矿的数量会消失;每天矿里的数量呈等差数列的减少,给你几条路,为矿到达另一矿所用的时间
在一个矿中,待一天必须离开
题解: dp
dp[i][j] 表示第i 天 到达j 矿 所得到的最大矿量
dp[i][j]=max(dp[i][j],dp[i-time][k]+max(0,g[j]-d[j]*(i-1)))
k 表示j 矿前的矿,要保证在i-time 天 k 矿收集过矿石。
然后三层循环,竟然不会超时。。。。。。。
c++ code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e3+10; struct Node{ int to,time; }; vector<Node>edge[N]; ll dp[N][N]; int g[N],d[N]; int main() { memset(dp,0,sizeof(dp)); int n,m; int u,v,t; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&g[i],&d[i]); while(m--) { scanf("%d%d%d",&u,&v,&t); Node p; p.time=t; p.to=v; edge[u].push_back(p); p.to=u; edge[v].push_back(p); } dp[1][1]=g[1]; for(int i=1;i<=1001;i++) { for(int j=1;j<=n;j++) { for(int k=0;k<edge[j].size();k++) { int to=edge[j][k].to; int time=edge[j][k].time; if(i-time>=1&&dp[i-time][to]) dp[i][j]=max(dp[i][j],dp[i-time][to]+max(0,g[j]-(i-1)*d[j])); } // printf("%d,%d %d\n",i,j,dp[i][j]); } } ll ans=0; for(int i=0;i<=1001;i++) for(int j=1;j<=n;j++) ans=max(ans,dp[i][j]); printf("%lld\n",ans); return 0; }