码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1110 : [POI2007]砝码Odw

时间:2015-07-01 22:12:37      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

砝码从小到大放最优,二分答案mid,转化为判定前mid小的砝码能否放完。

从大到小考虑砝码,依次扫描每个容器,能放就放。

由于砝码重量都成倍数关系,所以最多只有$O(\log n)$种不同的数字,所以总复杂度为$O(n\log^2n)$。

 

#include<cstdio>
#include<algorithm>
#define N 100010
int n,m,i,j,k,t,a[N],b[N],c[N],l,r,mid,ans;
inline void read(int&a){char c;while(!(((c=getchar())>=‘0‘)&&(c<=‘9‘)));a=c-‘0‘;while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10)+=c-‘0‘;}
bool check(int x){
  for(i=1;i<=n;i++)c[i]=a[i];
  for(;x;x=j){
    for(j=x-1;b[x]==b[j];j--);
    for(t=x-j,i=1;i<=n&&t;i++){
      k=c[i]/b[x];
      if(k>t)k=t;
      c[i]-=k*b[x],t-=k;
    }
    if(t)return 0;
  }
  return 1;
}
int main(){
  read(n),read(m);
  for(i=1;i<=n;i++)read(a[i]);
  for(i=1;i<=m;i++)read(b[i]);
  std::sort(b+1,b+m+1),l=1,r=m;
  while(l<=r)if(check(mid=(l+r)>>1))l=(ans=mid)+1;else r=mid-1;
  return printf("%d",ans),0;
}

  

BZOJ1110 : [POI2007]砝码Odw

标签:

原文地址:http://www.cnblogs.com/clrs97/p/4614599.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!