COJ1023(修路)

题目链接

题目的模型为给定含m个数的数列,将其分为连续的n段,使每段的和的最大值最小(刘汝佳白书上有)。由于是连续的,题目就简单了,之前就是没注意到这点,想了好久都没思路。我们可以首先可以确定结果的上界和下界,然后使用二分法将这个区间不断缩小,这个过程中要判断对于一个给定的x,是否能够在x天内修完路,因为路段是连续的,所以可以使用贪心来判断,贪心策略为,从第一个数开始,将尽量多的数分配到第一段,以此类推,直至分配完成,若分配的段数大于n则无法在x天内完成,否则可以。

 1 #include <stdio.h> 
2 #define MAX(a,b) ((a)>(b)?(a):(b))
3 #define N 305
4 int a[N],n,m;
5 int judge(int t)
6 {
7   int i=0,tmp,cnt=0;
8   while(i<m)
9   {
10     if(t<a[i]) return 0;
11     tmp=0;
12     while(tmp+a[i]<=t) tmp+=a[i++];
13     cnt++;
14   }
15   return cnt<=n?1:0;
16 }
17 int main()
18 {
19   int i,t,min,max,mid;
20   scanf("%d",&t);
21   while(t--)
22   {
23     min=max=0;
24     scanf("%d%d",&m,&n);
25     for(i=0; i<m; i++)
26     {
27       scanf("%d",&a[i]);
28       min=MAX(min,a[i]);
29       max+=a[i];
30     }
31     min--;
32     while(min+1!=max)
33     {
34       mid=(min+max)>>1;
35       if(judge(mid)) max=mid;
36       else min=mid;
37     }
38     printf("%d\n",max);
39   }
40   return 0;
41 }

 

你可能感兴趣的:(OJ)