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 n n n and m m m ( 1 ≤ n , m ≤ 100000 ) (1≤n,m≤100 000) (1n,m100000), separated by a singlespace, denoting respectively: the number of containers and the number of weights. The second line of thestandard input consists of n n n integers w i w_i wi ( 1 ≤ w i ≤ 1   000   000   0001 ≤ w i ≤ 1000000000 , f o r 1 ≤ i ≤ n 1 ≤ 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) (1wi1 000 000 0001wi1000000000,for1in1in), separated by single spaces,denoting the strengths of containers in milligrammes. In the third line there are m m m integers m j ( 1 ≤ m j ≤ 1   000   000   000   f o r 1 ≤ j ≤ m ) m_j(1\le m_j\le 1\ 000\ 000\ 000\ for 1\le j\le m) mj(1mj1 000 000 000 for1jm), 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值