Bessie is conducting a business trip in Bovinia, where there are?NN?(2≤N≤10002≤N≤1000) cities labeled?1…N1…N?connected by?MM?(1≤M≤20001≤M≤2000) one-way roads. Every time Bessie visits city?i,i,?Bessie earns?mimi?moonies (0≤mi≤10000≤mi≤1000). Starting at city 1 Bessie wants to visit cities to make as much mooney as she can, ending back at city 1. To avoid confusion,?m1=0.m1=0.
Mooving between two cities via a road takes one day. Preparing for the trip is expensive; it costs?C?T2C?T2?moonies to travel for?TT?days (1≤C≤10001≤C≤1000).
What is the maximum amount of moonies Bessie can make in one trip? Note that it may be optimal for Bessie to visit no cities aside from city 1, in which case the answer would be zero.
The first line contains three integers?NN,?MM, and?CC.The second line contains the?NN?integers?m1,m2,…mNm1,m2,…mN.
The next?MM?lines each contain two space-separated integers?aa?and?bb?(a≠ba≠b) denoting a one-way road from city?aa?to city?bb.
A single line with the answer.
3 3 1 0 10 20 1 2 2 3 3 1
24
The optimal trip is?1→2→3→1→2→3→1.1→2→3→1→2→3→1.?Bessie makes?10+20+10+20?1?62=2410+20+10+20?1?62=24?moonies in total.
Problem credits: Richard Peng and Mark Gordon
<h3> USACO 2020 January Contest, Gold Problem 1. Time is Mooney 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Benjamin Qi)
If Bessie travels for exactly?tt?days then the amount of moonies that she makes is bounded above by?1000t?t2,1000t?t2,?which is negative when?t>1000.t>1000.?Thus, it suffices to keep track of the DP states?dp[x][t]dp[x][t]?for each?1≤x≤N,0≤t≤1000,1≤x≤N,0≤t≤1000,?denoting the maximum amount of moonies Bessie can make up to time?tt?if she is located at city?xx?at time?tt. The final answer will be?max0≤t≤1000(dp[1][t]?Ct2).max0≤t≤1000(dp[1][t]?Ct2).?This solution runs in?O(max(mi)?(N+M)).O(max(mi)?(N+M)).?time.
Mark Chen's code:
#include <bits/stdc++.h> using namespace std; const int MAXN = 1005; const int MAXT = 1005; long long n, m, c; long long value[MAXN]; long long dp[2][MAXN]; vector<pair<int, int>> edges; int main() { freopen("time.in","r",stdin); freopen("time.out","w",stdout); cin >> n >> m >> c; for (int i = 1; i <= n; i++) { cin >> value[i]; } int a, b; for (int i = 0; i < m; i++) { cin >> a >> b; edges.push_back(make_pair(a, b)); } long long max_profit = 0; memset(dp, -1, sizeof dp); dp[0][1] = 0; for (int t = 1; t < MAXT; t++) { int p = t % 2; memset(dp[p], -1, sizeof dp[p]); for (auto& e : edges) { a = e.first; b = e.second; if (dp[1-p][a] >= 0) { dp[p][b] = max(dp[p][b], dp[1-p][a] + value[b]); } } max_profit = max(max_profit, dp[p][1] - c * t * t); } cout << max_profit << "\n"; }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1