702:Crossing River (贪心)
【题目描述】
N个人过河,一次过去2个回来一个,给出每个人所需时间,问最小过河时间。
【题目链接】
http://noi.openjudge.cn/ch0406/702/
【算法】
一开始想样例是怎么成立的想了半天,因为一开始以为贪心策略就是最小的人陪每个人过去然后回来,这样子的话样例应该是19。样例:4个人,时间分别为:1 2 5 10。最少时间为17。策略是最小和次小先过去,然后最小回来,最大和次大过去,次小回来,然后最小次小再过去结束。然后按这种策略写wa了,没办法。查了一波题解,发现两种策略去最小。。。。晕。因为假设递增的a,b,c,d四个人,两种策略所需时间分别为:2*b+a+d+b和a*2+c+d+b,消去相同项为2*b和a+c,所以每次取两者最小就行了(第二种策略很容易构造出数据: 1 99 100 1000)。当然在剩三个人的情况下,两种策略用时相同都是a+b+c。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 int t,n,i,ans; 4 int a[1010]; 5 int main() 6 { 7 scanf("%d",&t); 8 while(t--) { 9 ans=0; 10 scanf("%d",&n); 11 for(i=1;i<=n;i++) scanf("%d",&a[i]); 12 if(n==1) { printf("%d\n",a[1]); continue; } 13 sort(a+1,a+n+1); 14 for(i=n;i>3;i-=2) 15 ans+=min(a[1]+2*a[2]+a[i],a[1]*2+a[i]+a[i-1]); 16 if(n&1) ans+=a[1]+a[2]+a[3]; 17 else ans+=a[2]; 18 printf("%d\n",ans); 19 } 20 return 0; 21 }