CSU1976: 搬运工小明

Description

作为老人的小明非常忧伤,因为他马上要被流放到本部去了,住进全左家垅最有历史感的11舍真是一件非常荣幸的事情。
搬行李是个体力活,小明发现自己的行李太多啦,所以他决定去买很多个袋子来装走。到了超市的小明发现,不同大小的袋子居然价格一样???虽然买最大的自然最赚,但是小明是名远近闻名的环保人士,他觉得袋子只要能装下他的行李就够了,并且为了不麻烦收银的小姐姐(⊙o⊙)…,他也只会购买同一种大小的袋子。因此他希望在能装下所有行李的前提下,袋子越小越好。同时为了避免弄乱行李,小明希望同一个袋子装的是位置连续相邻的行李。
小明摸了摸口袋发现自己带的钱最多能买N个袋子,数学特别差的他不知道到底该买多大的才合适,所以想靠你来解决这个问题了。

Input

第一行为一个数字T(T<=10)表示数据组数
第二行为两个数字N(N <= 10^5)和 M(M <= 10^5)表示袋子个数和小明的行李个数
第三行为M个数字,第i个数字a[i]表示小明的第i个行李体积为a[i](0<a[i] <= 10^9)

Output

输出一行表示袋子的最小体积(整数)

Sample Input

1
3 3
1 1 1

Sample Output

1

Hint

袋子不能装下体积大于其容积的物品
多个物品满足体积之和小于等于一个袋子的容积,就能被装进

Source

2017年8月月赛

Author

卢铭威

 
简单的二分。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 long long T,n,m;
 8 long long ans,maxn=0;
 9 long long c[100005];
10 
11 int main()
12 {
13     scanf("%lld",&T);
14     while(T--)
15     {
16         ans=0;
17         maxn=0;
18         memset(c,0,sizeof(0));
19         scanf("%lld%lld",&n,&m);
20         for(int i=0;i<m;i++)
21         {
22             scanf("%lld",&c[i]);
23             ans+=c[i];
24             if(c[i]>maxn)
25                 maxn=c[i];
26         }
27 
28         long long low=maxn,hign=ans,mid;
29         //cout<<low<<" "<<hign<<endl;
30         long long i=0,s=0;
31         while(hign>low)
32         {
33             i=0,s=0;
34             mid=(low+hign)/2;
35             long long d=0;
36             while(i<m)
37             {
38                 d+=c[i];
39                 if(d<mid)
40                     i++;
41                     else
42                     {
43                         if(d>mid)
44                         {
45                             d=0;
46                             s++;
47                         }
48                         else
49                         {
50                             if(d==mid)
51                             {
52                                 d=0;
53                                 s++;
54                                 i++;
55                             }                    
56                         }
57                     }
58                 //cout<<d<<" "<<i<<endl;
59             }
60             if(d>0)
61                 s++;
62             //cout<<s<<" "<<mid<<endl;
63             if(s>n)
64                 low=mid+1;
65                 else
66                     hign=mid;
67         }
68         printf("%lld\n",(hign+low)/2);
69     }
70     
71     
72     return 0;
73 } 

 

posted @ 2017-08-14 08:35  西北会法语  阅读(706)  评论(0编辑  收藏  举报