bzoj 1110 [POI2007]砝码Odw 贪心+进制转化

 [POI2007]砝码Odw

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 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

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 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682110.html