标签:
砝码从小到大放最优,二分答案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;
}
标签:
原文地址:http://www.cnblogs.com/clrs97/p/4614599.html