bzoj 1110 [POI2007]砝码Odw 贪心+进制转化
[POI2007]砝码Odw
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 661 Solved: 366
[Submit][Status][Discuss]
Description
在byteotian公司搬家的时候,他们发现他们的大量的精密砝码的搬运是一件恼人的工作。公司有一些固定容
量的容器可以装这些砝码。他们想装尽量多的砝码以便搬运,并且丢弃剩下的砝码。每个容器可以装的砝码数量有
限制,但是他们能够装的总重量不能超过每个容器的限制。一个容器也可以不装任何东西。任何两个砝码都有一个
特征,他们的中总有一个的重量是另外一个的整数倍,当然他们也可能相等。
Input
第一行包含两个数n和m。表示容器的数量以及砝码的数量。(1<=n, m<=100000) 第二行包含n个整数wi,表示
每个容器能够装的最大质量。(1<=wi<=1000000000) 第三行包含m个整数mj,表示每个砝码的质量。(1<=mj<=10000
00000)
Output
仅包含一个数,为能够装进容器的最多的砝码数量。
Sample Input
2 4
13 9
4 12 2 4
13 9
4 12 2 4
Sample Output
3
HINT
题解:因为任意两个数,一个一定是另外一个的整数倍
所以说,取最小的设为x,那么就是转化成x进制下,然后
就是从小到大贪心,如果当前位不够可以向高位借1
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 int n,m,len,ans; 7 int bas[50],w[100010],v[100010],c[50]; 8 int rd() 9 { 10 int ret=0,f=1; char gc=getchar(); 11 while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();} 12 while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); 13 return ret*f; 14 } 15 int main() 16 { 17 n=rd(),m=rd(); 18 int i,j; 19 for(i=1;i<=n;i++) w[i]=rd(); 20 for(i=1;i<=m;i++) v[i]=rd(); 21 sort(v+1,v+m+1); 22 for(i=1;i<=m;i++) 23 { 24 if(v[i]>bas[len]) bas[++len]=v[i]; 25 v[i]=len; 26 } 27 for(i=1;i<=n;i++) for(j=len;j;j--) c[j]+=w[i]/bas[j],w[i]%=bas[j]; 28 for(i=1;i<=m;i++) 29 { 30 if(c[v[i]]) c[v[i]]--,ans++; 31 else 32 { 33 for(j=v[i];j<=len;j++) 34 { 35 if(c[j]) 36 { 37 c[j]--; 38 break; 39 } 40 c[j]=bas[j+1]/bas[j]-1; 41 } 42 if(j>len) break; 43 else ans++; 44 } 45 } 46 printf("%d",ans); 47 return 0; 48 }