现在的位置: 首页 > 综合 > 正文

Timus 1826

2012年06月08日 ⁄ 综合 ⁄ 共 1049字 ⁄ 字号 评论关闭
#include <iostream>
#include
<vector>
#include
<algorithm>
using namespace std;

int main() {

vector
<int> times;
int n, min = 0, t, t1, t2;

cin
>>n;

for(int i=0;i<n;i++) {
cin
>>t;
times.push_back(t);
}

sort(times.begin(), times.end());

for(int i=times.size()-1; i >= 3; i-=2) {
t1
= times[1] + times[0] + times[i] + times[1];
t2
= times[i] + times[0] + times[i-1] + times[0];

if( t1 <= t2 ) {
times.pop_back();
times.pop_back();
min
+= t1;
}
else {
break;
}
}

for(int i=times.size()-1; i > 1; i--) {
min
+= times[i] + times[0];
times.pop_back();
}

if(times.size() == 2)
min
+= times[1];
else
min
+= times[0];

cout
<<min<<endl;

return 0;
}

咋看题意,比较单纯的我就以为每次只要用最快的人带另一个人过去对面,然后回来,这样就是最短时间。

但作者人很好,因为他在示例数据里面已经告诉所有像我那样单纯的人,这样的想法是不对的。

然而实在太单纯了,竟然不知道示例数据是如何计算出来的,唯有去看discuss了。

看过了以后知道了,如果有两个人,他们过对面花费的时间都很大,那么把这两个人捆绑一齐送过去,然后再把对面一个走得很快的人回来,这样可能更好。

明白了这一点后,我第一个反应就是DP,谁知道这题的DP是2^100 (n<=100),我知道自己又错了。

后来想了一下,只要总是比较一种情况,迭代到最后就可以了。

假设按耗时从低到高来排序所有人,那么得到序列T0,T1,...,Tn-2,Tn-1

那么到底把两个走得慢的人捆绑到对面,再送一个“快人”回来的优势有多大呢?算一下就好,取哪两个“慢人”好呢?当然是最慢的。

T1(两个“快人”过去) + T0(最快的人回来)+ Tn-1(最慢两人过去) + T1(次快的人回来)

然后就这样把两个最慢的人送过去了,而常规的,用最快的人分别送这两个慢人过去的计算就不说了。 比较一下就知道哪个方案的优势高。

如果对最慢的两个人都失去优势,那么对其他剩下的人也是。

抱歉!评论已关闭.