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 }
时间: 2024-10-28 08:48:06