要求装走最多数量而不是最重,,这启示我们从最轻的开始贪心。
我们发现权值太多,又不知道每个东西应该装哪个箱子最优。
认真读题:砝码重量成比例。
成比例,,那就可以除以一个数让它们变小,,那这个数可以视作重量的进制,。所以我们亦可以将箱子表示成进制状态。
那每个箱子被拆分成了不同的进制。最后从小到大走一遍。如果当前没有箱子,我们大可以找个更大的箱子把它拆开。这样做是对的,因为就算我们放弃当前小砝码,那以后还得用那个大箱子最多贡献1.还不如拆成很多个小箱子造福社会。
如果实在没法子,,那就GG。
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define in read()
int in{
int cnt=0,f=1;char ch=0;
while(!isdigit(ch)){
ch=getchar();if(ch=='-')f=-1;
}
while(isdigit(ch)){
cnt=cnt*10+ch-48;
ch=getchar();
}return cnt*f;
}
int n,m;
int a[100003],b[100003];
int c[100003],cnt[100003];int tot;
bool have(int now){
for(int i=now+1;i<=tot;i++){
if(cnt[i]){
cnt[i]--;cnt[now]+=c[i]/c[now];return true;
}
}return false;
}
signed main(){
n=in;m=in;for(int i=1;i<=n;i++)a[i]=in;for(int j=1;j<=m;j++)b[j]=in;
sort(a+1,a+n+1);sort(b+1,b+m+1);
for(int i=1;i<=m;i++)if(b[i]!=b[i-1])c[++tot]=b[i];
for(int i=1;i<=n;i++){
for(int j=tot;j>=1;j--){
while(a[i]>=c[j]){
a[i]-=c[j];cnt[j]++;
}
}
}int now=1;
for(int i=1;i<=m;i++){
int x=b[i];
while(x>c[now])++now;
x=c[now];
if(cnt[now])cnt[now]--;
else{
if(have(now))cnt[now]--;
else{
cout<<i-1;return 0;
}
}
}
cout<<m;
return 0;
}