思路:
离散化之后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) 41 dp[i][j] = min(dp[i][j], 42 dp[i][l + 1] + (abs(v[j] - v[l + 1]) + 1 >> 1)); 43 } 44 for (int j = r + 1; j < m; j++) 45 { 46 dp[i][j] = dp[i][r] + (abs(v[j] - v[r] + 1) >> 1); 47 if (l < r) 48 dp[i][j] = min(dp[i][j], 49 dp[i][r - 1] + (abs(v[j] - v[r - 1]) + 1 >> 1)); 50 } 51 } 52 cout << *min_element(dp[n], dp[n] + m) << endl; 53 } 54 return 0; 55 }