题目描述
对于给定的一个长度为N的正整数数列A-iA−i,现要将其分成M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小。
关于最大值最小:
例如一数列4 2 4 5 142451要分成33段
将其如下分段:
[4 2][4 5][1][42][45][1]
第一段和为66,第22段和为99,第33段和为11,和最大值为99。
将其如下分段:
[4][2 4][5 1][4][24][51]
第一段和为44,第22段和为66,第33段和为66,和最大值为66。
并且无论如何分段,最大值不会小于66。
所以可以得到要将数列4 2 4 5 142451要分成33段,每段和的最大值最小为66。
输入输出格式
输入格式:
第11行包含两个正整数N,M。
第22行包含NN个空格隔开的非负整数A_iAi,含义如题目所述。
输出格式:
一个正整数,即每段和最大值最小为多少。
输入输出样例
说明
对于20\%20%的数据,有N≤10N≤10;
对于40\%40%的数据,有N≤1000N≤1000;
对于100\%100%的数据,有N≤100000,M≤N, A_iN≤100000,M≤N,Ai之和不超过10^9109。
题目都很水
规范二分写法!!!
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 214748347 #define N 100005 int a[N]; int main() { int n,k; RII(n,k); int R=0; int L=0; rep(i,1,n) { RI(a[i]);R+=a[i]; L=max(L,a[i]); } while(L<R) { int mid=(L+R)>>1; int cnt=0; int temp=0; rep(i,1,n) { temp+=a[i]; if(temp>mid) cnt++,temp=a[i]; } if(temp)cnt++; if(cnt>k)L=mid+1; else R=mid;//答案求的是最小值 所以当有=时右往左靠 } cout<<L; return 0; }
题目描述
陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢?
输入输出格式
输入格式:
第一行,两个整数,A,B。(B<=A<=100000)
第二行,A个整数,分别为这A个瓶盖坐标。
输出格式:
仅一个整数,为所求答案。
输入输出样例
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 214748347 #define N 100005 ll a[N]; int n,k; bool check(ll x)//x为最近距离 { int cnt=1; int temp=1; rep(i,2,n) { if(a[i]-a[temp]>=x) cnt++,temp=i; } return cnt>=k; } int main() { RII(n,k); rep(i,1,n) cin>>a[i]; sort(a+1,a+1+n); ll R=a[n]-a[1]; ll L=0; ll ans=0; while(L<=R) { ll mid=(L+R)>>1; if(check(mid))L=mid+1,ans=max(ans,mid); else R=mid-1; } cout<<L-1; return 0; }
其他写法:
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 214748347 #define N 100005 ll a[N]; int n,k; bool check(ll x)//x为最近距离 { int cnt=1; int temp=1; rep(i,2,n) { if(a[i]-a[temp]>=x) cnt++,temp=i; } return cnt>=k; } int main() { RII(n,k); rep(i,1,n) cin>>a[i]; sort(a+1,a+1+n); ll R=a[n]-a[1]; ll L=0; ll ans=0; while(L<R) { ll mid=(L+R+1)>>1; if(check(mid))L=mid; else R=mid-1; } cout<<L; return 0; }
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);i--) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 214748347 #define N 100005 ll a[N]; int n,k; bool check(ll x)//x为最近距离 { int cnt=1; int temp=1; rep(i,2,n) { if(a[i]-a[temp]>=x) cnt++,temp=i; } return cnt>=k; } int main() { RII(n,k); rep(i,1,n) cin>>a[i]; sort(a+1,a+1+n); ll R=a[n]-a[1]; ll L=0; ll ans=0; while(L<=R) { ll mid=(L+R)>>1; if(check(mid))L=mid+1; else R=mid-1; } cout<<L-1; return 0; }