poj1700

题意:只有一艘船,能乘2人,船的运行速度为2人中较慢一人的速度,过去后还需一个人把船划回来,问把n个人运到对岸,最少需要多久。

分析:我们设最快的为a,次快的为b,最慢的为z,次慢的为y。

我们先考虑如何将y,z运到对岸,可以ab,a,yz,b,也可以ay,a,az,a。

运送z不可能影响此4人之外的人,因为船只能乘2人,z要带也是带次慢的。

那如果是单运z,然后x和y一起运呢?这种情况是不可能存在的。

通过不等式可以证明如果单运y,z比一起运快,那么yx一起运绝对比单运y,x慢,所以不用考虑单运z必然单运y

2a + y + z < 2b + a + z     =>      2a + x + y < 2b + a + y

这样每次运最后两个可以一直让总数减少直到3个以内,直接处理即可

View Code
#include < iostream >
#include
< cstdio >
#include
< cstdlib >
#include
< cstring >
#include
< algorithm >
using namespace std;

#define maxn 1006

int n, f[maxn];

int cal( int a, int b, int y, int z)
{
return min(z + a + y + a, b + a + z + b);
}

void work()
{
int i = n - 1 ;
int ans = 0 ;
while (i > 2 )
{
ans
+= cal(f[ 0 ], f[ 1 ], f[i - 1 ], f[i]);
i
-= 2 ;
}
if (i == 2 )
ans
+= f[ 0 ] + f[ 1 ] + f[ 2 ];
else
ans
+= f[ 1 ];
printf(
" %d\n " , ans);
}

int main()
{
// freopen("t.txt", "r", stdin);
int t;
scanf(
" %d " , & t);
while (t -- )
{
scanf(
" %d " , & n);
for ( int i = 0 ; i < n; i ++ )
scanf(
" %d " , & f[i]);
sort(f, f
+ n);
if (n == 1 )
{
printf(
" %d\n " , f[ 0 ]);
continue ;
}
work();
}
return 0 ;
}

你可能感兴趣的:(poj)