搜索的应用--计算最优解:Aizu - ALDS1_4_D Allocation

搜索的应用-计算最优解

题目:

You are given nn packages of wiwi kg from a belt conveyor in order (i=0,1,...n−1i=0,1,...n−1). You should load all packages onto kk trucks which have the common maximum load PP. Each truck can load consecutive packages (more than or equals to zero) from the belt conveyor unless the total weights of the packages in the sequence does not exceed the maximum load PP.

Write a program which reads nn, kk and wiwi, and reports the minimum value of the maximum load PP to load all packages from the belt conveyor.

Input

In the first line, two integers nn and kk are given separated by a space character. In the following nn lines, wiwi are given respectively.

Output

Print the minimum value of PP in a line.

Constraints

  • 1≤n≤100,0001≤n≤100,000
  • 1≤k≤100,0001≤k≤100,000
  • 1≤wi≤10,0001≤wi≤10,000

Sample Input 1

5 3

8

1

7

3

9

Sample Output 1

10

If the first truck loads two packages of {8,1}{8,1}, the second truck loads two packages of {7,3}{7,3} and the third truck loads a package of {9}{9}, then the minimum value of the maximum load PP shall be 10.

 

Sample Input 2

4 2

1

2

2

6

Sample Output 2

6

If the first truck loads three packages of {1,2,2}{1,2,2} and the second truck loads a package of {6}{6}, then the minimum value of the maximum load PP shall be 6.

思路:

其实这道题目的思路非常简单,就是需要看清楚题目的意思,还有要小心TLE。为:只要卡车的运载量没有达到P,我们就让其按照顺序装货物,最后在计算所有卡车运载量的总和即可。这里以P为实参,编写一个返回可装载货物数v的函数v=f(P)。这函数的算法复杂度为O(n)。然后只要调用这个函数,利用“P增加,v也增加”(严格来说是P增加v也不会减少)的性质,用二分法搜索求P。此时算法的复杂度为O(nlogP)。

 

代码:

 

 1 #include <iostream>
 2 
 3 using namespace std;
 4 #define MAX 100000
 5 typedef long long llong;
 6 int n,k;
 7 llong T[MAX];
 8 
 9 int check(llong P)
10 {
11     int i=0;
12     for(int j=0;j<k;j++)
13     {
14         llong s=0;
15         while(s+T[i]<=P)
16         {
17             s+=T[i];
18             i++;
19             if(i==n) return n;
20         }
21     }
22     return i;
23 }
24 
25 int solve()
26 {
27     llong left=0;
28     llong right=100000*10000;
29     llong mid;
30     while(right-left>1)
31     {
32         mid=(right+left)/2;
33         int v=check(mid);
34         if(v>=n) right=mid;
35         else
36             left=mid;
37     }
38     return right;
39 }
40 
41 int main()
42 {
43     cin>>n>>k;
44     for(int i=0;i<n;i++)
45     {
46         cin>>T[i];
47     }
48     llong ans=solve();
49     cout<<ans<<endl;
50     return 0;
51 }

 

 

总结:

题目说了,是在传送带上依次送来的货物,意思就是说,只要传送带送来了货物,就要将其装载到货车上。而在第一次看到题目的时候没有注意到这个依次,所以,总是弄不明白书上的思路,浪费了很多的时间。

上一篇:存储过程


下一篇:模板 - n个数的乘法逆元