Luogu P3462 [POI2007]ODW-Weights
题目描述
While moving to a new compound the Byteotian Institute of Experimental Physics has encountered a logisticalproblem - the transfer of its vast collection of precision weights turned out to be non-trivial.
The Institute has a certain number of containers of limited strength at its disposal. As many weightsas possible are to be put into the containers, the remaining ones will be discarded. There is no limit onthe number of weights to be put in a container apart from the requirement of not exceeding its strength. Acontainer may also be empty.
Any two weights in the Institute have a peculiar property: the mass of one of them is an integer multipleof the mass of the other. Particularly, they may have the same mass.
TaskWrite a programme which:
reads the durabilities of the containers and masses of the weights from the standard input, determines the maximal number of weights that can be put in the containers, writes the outcome to the standard output.
在byteotian公司搬家的时候,他们发现他们的大量的精密砝码的搬运是一件恼人的工作。公司有一些固定容量的容器可以装这些砝码。他们想装尽量多的砝码以便搬运,并且丢弃剩下的砝码。每个容器可以装的砝码数量有限制,但是他们能够装的总重量不能超过每个容器的限制。一个容器也可以不装任何东西。任何两个砝码都有一个特征,他们的中总有一个的重量是另外一个的整数倍,当然他们也可能相等。
输入输出格式
输入格式:
The first line of the standard input contains two integers nnn and mmm(1≤n,m≤100000)(1≤n,m≤100 000)(1≤n,m≤100000), separated by a singlespace, denoting respectively: the number of containers and the number of weights. The second line of thestandard input consists of nnn integers wiw_iwi (1≤wi≤1 000 000 0001≤wi≤1000000000,for1≤i≤n1≤i≤n)(1\le w_i\le 1\ 000\ 000\ 0001≤w_i ≤1 000 000 000 ,for 1\le i\le n1≤i≤n)(1≤wi≤1 000 000 0001≤wi≤1000000000,for1≤i≤n1≤i≤n), separated by single spaces,denoting the strengths of containers in milligrammes. In the third line there are mmm integers mj(1≤mj≤1 000 000 000 for1≤j≤m)m_j(1\le m_j\le 1\ 000\ 000\ 000\ for 1\le j\le m)mj(1≤mj≤1 000 000 000 for1≤j≤m), separated by single spaces, denoting masses of the weights in milligrammes.
输出格式:
The first and only line of the standard output should contain a single integer -the maximal number ofweights that can be placed in the containers without exceeding their durability.
输入输出样例
输入样例#1:
2 4
13 9
4 12 2 4
输出样例#1:
3
贪心
我们要充分利用题目中“任意两个砝码中有一个是另一个的整数倍”的性质。首先一个很显然的结论就是尽量取小的砝码。我们要考虑的是取小砝码的时候放在哪些容器中。根据题目的特殊性质,可以将砝码的重量看做一个进制(进制数不固定)。然后将容器进行进制拆分,每一位上的数全部累加起来。放砝码的时候就是高精度减法,直到不能放为止。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<ctime> #include<queue> #include<iomanip> #define ll long long #define N 100005 using namespace std; inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} int n,m,cc; int c[N],w[N]; int d[N]; int ans; int cnt[N]; int a[N]; struct node { int v; int key; bool operator <(const node &a)const { if(key!=a.key) return key<a.key; return v<a.v; } }; priority_queue<node>q; bool reduce(int v) { a[v]--; while(a[v]<0&&v<cc) { a[v]+=d[v+1]/d[v]; a[++v]--; } return (v<cc); } int main() { n=Get(),m=Get(); for(int i=1;i<=n;i++) c[i]=Get(); for(int i=1;i<=m;i++) w[i]=Get(); sort(c+1,c+1+n); sort(w+1,w+1+m); for(int i=1;i<=n;i++) c[i]/=w[1]; for(int i=m;i>=1;i--) w[i]/=w[1]; for(int i=1;i<=m;i++) d[i]=w[i]; sort(d+1,d+1+m); cc=unique(d+1,d+1+m)-d; int now=0; d[cc]=d[cc-1]*2; for(int i=1;i<=n;i++) { for(int j=1;j<cc&&c[i];c[i]/=d[j+1]/d[j],j++) { if(j<cc-1) a[j]+=c[i]%(d[j+1]/d[j]); else a[j]+=c[i]; } } for(int i=1;i<=m;i++) { if(w[i]!=w[i-1]) now++; if(reduce(now)) ans++; else break; } cout<<ans<<"\n"; return 0; }