百度之星2019第一场1002 Game

思路:

离散化之后dp,dp[i][j]表示完成前i个任务并且处在第j个点所需要的最小代价。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 pair<int, int> a[1005];
 4 int dp[1005][4005];
 5 int main()
 6 {
 7     ios::sync_with_stdio(false);
 8     int T, n; cin >> T;
 9     while (T--)
10     {
11         cin >> n;
12         vector<int> v;
13         for (int i = 1; i <= n; i++)
14         {
15             cin >> a[i].first >> a[i].second;
16             v.push_back(a[i].first);
17             v.push_back(a[i].second);
18             if (a[i].first < a[i].second - 1)
19             {
20                 v.push_back(a[i].first + 1);
21                 v.push_back(a[i].second - 1);
22             }
23         }
24         sort(v.begin(), v.end());
25         v.erase(unique(v.begin(), v.end()), v.end());
26         int m = v.size();
27         for (int i = 1; i <= n; i++)
28         {
29             a[i].first = lower_bound(v.begin(), v.end(), a[i].first) - v.begin();
30             a[i].second = lower_bound(v.begin(), v.end(), a[i].second) - v.begin();
31         }
32         for (int i = 0; i < m; i++) dp[0][i] = 0;
33         for (int i = 1; i <= n; i++)
34         {
35             int l = a[i].first, r = a[i].second;
36             for (int j = l; j <= r; j++) dp[i][j] = dp[i - 1][j];
37             for (int j = 0; j < l; j++)
38             {
39                 dp[i][j] = dp[i][l] + (abs(v[j] - v[l]) + 1 >> 1);
40                 if (l < r) dp[i][j] = min(dp[i][j], dp[i][l + 1] + (abs(v[j] - v[l + 1]) + 1 >> 1));
41             }
42             for (int j = r + 1; j < m; j++)
43             {
44                 dp[i][j] = dp[i][r] + (abs(v[j] - v[r] + 1) >> 1);
45                 if (l < r) dp[i][j] = min(dp[i][j], dp[i][r - 1] + (abs(v[j] - v[r - 1]) + 1 >> 1));
46             }
47         }
48         cout << *min_element(dp[n], dp[n] + m) << endl;
49     }
50     return 0;
51 }

 

上一篇:POJ-2236(并查集)


下一篇:P1550 [USACO08OCT]Watering Hole G