题解 P3462 【[POI2007]ODW-Weights】
VioletIsMyLove · · 题解
砝码两两互为倍数关系,从小到大排个序,可以发现不同的砝码种类数是
根据贪心的思想,砝码从小到大依次装入一定是最优的,把每个容器的容量写成砝码大小的进制表示,比如当有
把所有容器都写成这种表示,并把同一位上全部累加。比如说我们还有一个容器
当我们正在放大小为
接下来要放大小为
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int n,m,a[maxn],b[maxn],num[maxn],c[35],tot,cnt[35];
int read(){
int ret=0,f=1;char ch=getchar();
while (!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while (isdigit(ch)) ret=(ret<<3)+(ret<<1)+(ch&15),ch=getchar();
return ret*f;
}
int DFS(int id){//首先核对是否够-,不够要依次借位
if (id>tot)return 0;
if (cnt[id])return cnt[id]--,1;
if (DFS(id+1)){
cnt[id]+=c[id+1]/c[id],cnt[id]--;
return 1;
}
return 0;
}
int main(){
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=m;i++) b[i]=read();
sort(b+1,b+m+1);
for (int i=1;i<=m;i++){
if(b[i]!=b[i-1]) c[++tot]=b[i];
num[i]=tot;
}
for (int i=1;i<=n;i++)
for (int j=tot;j;j--)
cnt[j]+=a[i]/c[j],a[i]%=c[j];
for (int i=1;i<=m;i++){
if(!DFS(num[i])){printf("%d\n",i-1);return 0;}
if(i==m)printf("%d\n",m);
}
return 0;
}