POJ 1700 dp题解

来源:互联网 发布:苹果电脑怎么选 知乎 编辑:程序博客网 时间:2024/05/22 11:30

Crossing River

Time Limit:1000MS            Memory Limit:10000K

Description

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed;the speed of a couple is determined by the speed of the slower one.Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

141 2 5 10

Sample Output

17

Source

POJ Monthly--2004.07.18
 
样例数据解释:
第一步:第一个人和第二个人过去 第一个人回来 耗时2+1=3
第二步:第三个人和第四个人过去 第二个人回来 耗时10+2=12
第三步:第一个人和第二个人过去 耗时2
总计耗时:3+12+2=17
 
注意事项:
① 两个人在船上时,耗时为慢的那个人的耗时
② 船划过去之后,需要一个人划回来
③ 有多组测试数据
 
题目分析:
 
令time[i]为第i个人划船所耗的时间(1<=i<=N<=1000,1<=time[i]<=1000)
且当i<j时,time[i]<time[j]
 
当N=1时:耗时为time[1]
 
当N=2时:耗时为time[2]
 
当N=3时:
第一步:第一个人和第三个人过去 第一个人回来 耗时time[3]+time[1]
第二步:第一个人和第二个人过去 耗时time[2]
总计耗时:time[1]+time[2]+time[3]
 
当N=4时:
方案一:
第一步:第一个人和第四个人过去 第一个人回来 耗时time[4]+time[1]
第二步:第一个人和第三个人过去 第一个人回来 耗时time[3]+time[1]
*第三步:第一个人和第二个人过去 耗时time[2]
总计耗时:2*time[1]+time[2]+time[3]+time[4]
 
方案二:
第一步:第一个人和第二个人过去 第一个人回来 耗时time[2]+time[1]
第二步:第三个人和第四个人过去 第二个人回来 耗时time[4]+time[2]
*第三步:第一个人和第二个人过去 耗时time[2]
总计耗时:3*time[2]+time[1]+time[4]
 
对比两种方案可以发现:
两种方案的第三步是一样的
② 比较两种方案的优劣,即比较time[1]+time[3]2*time[2]的大小
③ 若均不做第三步,则两种方案均只是把最慢的人次慢的人送了过去,即把一个规模为N的问题转化为了一个规模为N-2的问题
 
类似上面的两种方案,我们可以通过耗时2*time[1]+time[N-1]+time[N]2*time[2]+time[1]+time[N]来把最慢的人次慢的人送过去
若要比较他们,则为比较time[1]+time[N-1]2*time[2]
 
令dp[i]为i个人过河的总耗时,则:
dp[1]=time[1]; dp[2]=time[2]; dp[3]=time[1]+time[2]+time[3];
当i>=4时 dp[i]=dp[i-2]+min(time[1]+time[i-1],2*time[2])+time[1]+time[i];
 
下面附上代码 
#include<cstdio>#include<algorithm>using namespace std;int main(){int T;scanf("%d",&T);for(int i=1;i<=T;i++){int N,time[1001],dp[1001];scanf("%d",&N);for(int j=1;j<=N;j++)scanf("%d",&time[j]);sort(time+1,time+N+1);dp[1]=time[1];dp[2]=time[2];dp[3]=time[1]+ti[2]+ti[3];for(int j=4;j<=N;j++)dp[j]=dp[j-2]+min(time[1]+time[j-1],2*time[2])+time[1]+time[j];printf("%d\n",dp[N]);}return 0;}</span>

0 0
原创粉丝点击