由于砝码质量成倍数,那么就可以把所有的盒子拆分成进制的形式,比如有1、2、4的砝码,那么容量为9的容器就写成(2,0,1)。把所有盒子的进制数组相加,累计每个进制位能放的数量。
计算答案时,我们可以贪心的考虑,由小到大放砝码更优,对于每一个砝码,找到其重量对应的进制,如果进制位上有值,直接加入即可;如果没有,找到其前方距离它最近的有值的进制,如果找不到,输出答案结束程序。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=100001;
int a[maxn],box[maxn],n,m,aa[maxn],ans,k,cnt,flag=1,f[33];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&box[i]);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m;i++)
if(a[i]!=a[i-1])
aa[++cnt]=a[i];//去重
for(int i=1;i<=n;i++)
for(int k=1;k<=cnt;k++)
{
f[k]+=box[i]/aa[k];
box[i]%=aa[k];
}//将容器拆分成进制
f[0]=1;
sort(a+1,a+1+m);
for(int i=1;i<=m;i++)
{
int x=a[i];
for(int j=cnt;j>=1;j--)
{
if(aa[j]<x) continue;
for(k=j;k>=0 && !f[k];k--);
if(!k)
{
printf("%d\n",ans);
return 0;
}
for(int p=k;p<j;p++)
f[p]--,f[p+1]+=aa[p]/aa[p+1];
f[j]--;
ans++;
break;
}
}
printf("%d\n",ans);
return 0;
}