1 条题解
-
0
#include<bits/stdc++.h> using namespace std; const int N=1e5+5,M=1e3+5; int n,m,k,x; int a[N],rnd[M]; int ans=1e9; void init() //看起来玄学的优化 { //注意到当最小值是x=m-1取到时 //当前的做法会TLE //所以考虑随机化枚举的过程 //枚举次数O(m)->O(ln(m)) for(int i=0;i<m;++i) rnd[i]=i; random_shuffle(rnd,rnd+m); } inline int mod(int v){return v<m?v:v-m;} bool calc(int limit) { //sum可以最开始就超过limit //这样就可以实现在每分一组令总数+1 //就不用再加尾判 int sum=limit+1,tot=0; for(int i=1;i<=n;++i) { int val=mod(a[i]+x); if(val>limit) return 0; sum+=val; if(sum>limit) sum=val,++tot; } return tot<=k; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;++i) scanf("%d",&a[i]); //发现不能直接计算x和最终结果关系 //注意到0<=x<m<=1000,所以考虑暴力枚举x init(); //求最大值的最小值 //所以考虑二分答案 for(int k=0;k<m;++k) { x=rnd[k]; int l=0,r=ans-1; //优化程度巨大的剪枝 //先判断它有没有可能成为更优解 if(!calc(r)) continue; while(l<=r) { int mid=(l+r)>>1; if(calc(mid)) r=mid-1,ans=mid; else l=mid+1; } } printf("%d",ans); return 0; }
- 1
信息
- ID
- 460
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 37
- 已通过
- 11
- 上传者