cf1504. Travelling Salesman Problem
cf1504. Travelling Salesman Problem
題意:
n個(gè)城市,編號1~n,每個(gè)城市有美麗值a[i],現(xiàn)在要從城市1出發(fā),其他所有城市走一遍,最后回到城市1,城市i到j(luò)的花費(fèi)為max(ci,aj-ai),ci為第i個(gè)城市的最低消費(fèi)
 最低的總消費(fèi)是多少?
題解:
(題解來自官方題解)
 費(fèi)用 = max (ci ,aj - ai)= ci +max(0,aj-ai-ci)
 因?yàn)樗谐鞘卸家?jīng)過,所以ci是固定消費(fèi),我們現(xiàn)在要做的就是最小化max(0,aj-ai-ci)的總和
 我們注意ai,ci一定是大于0的,要讓這個(gè)max最小化,我們就盡可能讓他等于0,也就是aj - (ai+ci)<=0
 如果ai>aj,那么從城市i到城市j就是免費(fèi)的(這里不考慮固定的ci消費(fèi),只考慮max的情況),所以我們只需要找一條從a1到an的路,剩下的旅程可以免費(fèi)完成,因?yàn)樽疃搪窂绞亲顑?yōu)的
 貼上原題解(說實(shí)話我現(xiàn)在還不是很清楚,等腦子清楚了再解決)
2021/4/21
 下午上java時(shí)突然明白了,為什么代碼里取max(mx, ve[i].first + ve[i].second);
 我們上面已經(jīng)推導(dǎo)出每個(gè)c都是計(jì)算在內(nèi)的,a是從小到大排序的,所以a[j]-a[i]一定大于等于0,c一定大于0,a[j]-a[i]-c[i]大小就不一定了,考慮到如果存在一個(gè)很大的ci,1可以通過它間接到達(dá)n,1借助當(dāng)前的ci能到達(dá)的最高的位置x,及比當(dāng)前的ai+aj大的ax+ay,這樣比1直接到達(dá)n的費(fèi)用更小。
代碼:
#include <bits/stdc++.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(0);int n;cin >> n;vector<pair<long long, long long>> ve;long long ans = 0;for(int i = 0; i < n; i++) {long long a, c;cin >> a >> c;ve.push_back({a, c});ans += c;}sort(ve.begin(), ve.end());//以a為第一元素,b為第二元素//城市的美麗值是遞增的 //for(int i=0;i<n;i++)// cout<<ve[i].first<<" "<<ve[i].second<<endl;long long mx = ve[0].first + ve[0].second;for(int i = 1; i < n; i++) {ans += max(0LL, ve[i].first - mx);mx = max(mx, ve[i].first + ve[i].second);}cout << ans << '\n'; } #include <bits/stdc++.h>using namespace std;int main() {int n;cin >> n;vector<pair<long long, long long> > city;long long ans = 0;for(int i = 0; i < n; i++) {long long a, c;cin >> a >> c;city.push_back({a, c});ans += c;}sort(city.begin(), city.end());priority_queue<pair<long long, int>> Q;vector<bool> vis(n, false);Q.push({0, 0});while(!Q.empty()) {long long d; int i;tie(d, i) = Q.top();//返回指向綁定的輸出流的指針。Q.pop();if(vis[i]) continue;vis[i] = true;if(i == n - 1) {ans -= d;break;}if(i > 0) {Q.push({d, i - 1});}int j = lower_bound(city.begin(), city.end(), make_pair(city[i].first + city[i].second, LLONG_MAX)) - city.begin() - 1;//LLONG_MAX均存在與頭文件limits.h,表示long long int Q.push({d, j});if(j + 1 < n) {Q.push({d - city[j + 1].first + city[i].first + city[i].second, j + 1});}}cout << ans << '\n'; }總結(jié)
以上是生活随笔為你收集整理的cf1504. Travelling Salesman Problem的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 《三国猛将传》怎么玩?《三国猛将传》新手
 - 下一篇: 提莫队长攻略、为什么团战可以输,提莫必须