1110: [POI2007]砝碼Odw 貪心 思路題
阿新 • • 發佈:2018-11-19
題解:
首先顯然是把砝碼從小到大裝進容器中,那麼如果我們能夠快速知道每次能否再放入砝碼,問題就迎刃而解了。題目有個重要條件:他們的中總有一個的重量是另外一個的整數倍,所以我們可以把每個容器用類似進位制轉換的方法表示,最高位的數字表示能裝最大的砝碼幾個,次高位表示儘量多的裝完最大砝碼,次大砝碼能裝的個數……以此類推,把所有容器的數加起來,然後每次裝入砝碼,相當於在某個位上 ,貪心就行了。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=100010;
const int inf=2147483647;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>= '0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int n,m,a[Maxn],b[Maxn],c[40],d[40],e[Maxn],l=0;
bool check(int p)
{
d[e[p]]--;
int t=e[p];
while(d[t]<0)
{
if(t==l)return false;
d[t]+=c[t+1]/c[t];d[t+1]--;
t++;
}
return true;
}
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+1+m);
int last=0;
for(int i=1;i<=m;i++)
{
if(b[i]==last){e[i]=l;continue;}
c[++l]=last=b[i];e[i]=l;
}
for(int i=1;i<=n;i++)
{
int t=a[i];
for(int j=l;j;j--)
if(t>=b[j])d[j]+=t/c[j],t%=c[j];
}
int ans=0;
for(int i=1;i<=m;i++)
{
if(check(i))ans++;
else break;
}
printf("%d",ans);
}