……睡太晚了。
。。脑子就傻了……
这个题想的时候并没有想到该这样……
题意大概是有n堆箱子从左往右依次排列,每堆ai个箱子,有m个人,最開始都站在第一个箱子的左边,
每个人在每一秒钟都必须做出两种选择中的一种:1若他的位置有箱子则搬走一个箱子,2往右走一步。
问把全部箱子都搞掉的最少时间……
非常显然二分一下答案,若为x秒,则每一个人都有x秒。一个一个排出去搬。看是否可以搬完……
我居然没想到……
#include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<iostream> #include<algorithm> #include<bitset> #include<climits> #include<list> #include<iomanip> #include<stack> #include<set> using namespace std; typedef long long ll; int a[100010]; bool isok(int n,int m,ll x) { ll t=x; for(int i=0;i<n;i++) { int re=a[i]; ll t1=t-i-1; if(t1<0) { if(m==0) return 0; t1=x-i-1; t=x; m--; } if(re>0) { if(t1>=re) t-=re; else { re-=t1; t1=x-i-1; t=x; int t2=re/t1; re-=t2*t1; if(re>0) { t2++; t-=re; } else t=0; m-=t2; if(m<0) return 0; } } } return 1; } int main() { int n,m; cin>>n>>m; for(int i=0;i<n;i++) cin>>a[i]; for(int i=n-1;i>-1;i--) if(a[i]!=0) { n=i+1; break; } ll l=n+1,r=ll(1e15); while(l<=r) { ll md=l+r>>1; if(isok(n,m-1,md)) r=md-1; else l=md+1; } cout<<l; }