ny716 River Crossing

River Crossing

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

Afandi is herding N sheep across the expanses of grassland  when he finds himself blocked by a river. A single raft is available for transportation.

 

Afandi knows that he must ride on the raft for all crossings, but adding sheep to the raft makes it traverse the river more slowly.

 

When Afandi is on the raft alone, it can cross the river in M minutes When the i sheep are added, it takes Mi minutes longer to cross the river than with i-1 sheep (i.e., total M+M1   minutes with one sheep, M+M1+M2 with two, etc.).

 

Determine the minimum time it takes for Afandi to get all of the sheep across the river (including time returning to get more sheep).

输入
On the first line of the input is a single positive integer k, telling the number of test cases to follow. 1 ≤ k ≤ 5 Each case contains:

* Line 1: one space-separated integers: N and M (1 ≤ N ≤ 1000 , 1≤ M ≤ 500).

* Lines 2..N+1: Line i+1 contains a single integer: Mi (1 ≤ Mi ≤ 1000)
输出
For each test case, output a line with the minimum time it takes for Afandi to get all of the sheep across the river.
样例输入
2    
2 10   
3
5
5 10  
3
4
6
100
1
样例输出
18
50
题目讲解:我和别人讨论很久才弄懂题目,有的说和过河问题很像,但是两个意思不同,又有很大的差别
我还是讲解一下大概意思吧,题中说道阿凡提需要把羊送到对面去,但是呢他只有一条船,而且他也可以选择每次带几个羊过去,
当然了,也可以一次性的带走完,带不完的话还要回来再带走,这样的话回来花的时间也要加上了,需要注意的是每个并羊没有对应的时间,
它所需要的时间取决于在这个时间顺序中她是第几个上船的;
下面看一下案列1:很显然羊是一下被带走完的,时间是3+5+10(自己的时间)=18分钟;
然而案例二却看不懂了吧,我就详细分析一下:首先是五个羊当然会有五个时间了,你有很多选择,一次带走完,一个一个的....
如果一次一个时间是多少呢?第一次走:3+10 回来:10 然后第二次再走:3+10(或许就在这疑惑了,怎么还是3呢为什么不是4呢,我说了羊没有对应的时间,
第一个上船的时间就是3,如果运两个羊第二个时间是4,然后回来后,又重新开始第一个,第二个....)然后又回来:10 第三次再走:3+10 回来:10 第四次再走3+10 回来:10
第五次再走:3+10 所以共:3+10 +10 +3+10 +10 +3+10 +10 +3+10 +10 +3+10=105分钟;
最优解应该是这个样子的第一次带三个羊:3+4+6+10 回来:10 再带走两个羊:3+4+10 共23+10+17=50分钟
参考代码如下:参考的大神的
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int  mmax=0x3fffffff;
 5 int a[1005],mmin[1005],m;
 6 int dp(int n)
 7 {
 8     if(n<=0)
 9         return 0;
10     if(mmin[n]!=mmax)
11         return mmin[n];
12     int ans=mmax;
13     for(int i=1;i<=n;i++)
14     {
15         if(dp(n-i)+a[i]+m<ans)
16              ans=dp(n-i)+a[i]+m;
17     }
18     return mmin[n]=ans;
19 }
20 int main()
21 {
22     int i,j,k,t,n;
23     scanf("%d",&t);
24     while(t--)
25     {
26         scanf("%d %d",&n,&m);
27         a[0]=m;
28         for(i=1;i<=n;i++)
29         {
30             scanf("%d",&a[i]);
31                a[i]+=a[i-1];
32               mmin[i]=mmax;
33         }
34        printf("%d\n",dp(n)-m);
35     }
36     return 0;
37 }

代码二:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <fstream>
 4 #include <cstring>
 5 #include <string>
 6 #include <cstdio>
 7 #include <cmath>
 8 using namespace std;
 9 int main()
10 {
11     int n,k,f[1500],ans[1500],l;
12     int i,m,j,temp;
13     scanf("%d",&k);
14         for(i=1;i<=k;i++)
15         {
16             memset(f,0,sizeof(f));
17             memset(ans,0,sizeof(ans));
18             scanf("%d %d",&n,&m);
19             f[0]=m;
20             for(j=1;j<=n;j++)
21             {
22 
23                 scanf("%d",&temp);
24                 f[j]=f[j-1]+temp;
25             }
26             ans[1]=f[1];
27             for(j=2;j<=n;j++)
28             {
29                 ans[j]=f[j];
30                 for(l=1;l<j;l++)
31                     if(ans[l]+ans[j-l]+m<ans[j])
32                         ans[j]=ans[l]+ans[j-l]+m; 
33             }
34             printf("%d\n",ans[n]);
35 
36         }
37     return 0;
38 }
39         

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值