解题报告: CF587A

题目链接:CF587A Duff and Weight Lifting
我又来做\(CF\)水题刷咕值了
我们可以考虑贪心,将尽可能多的\(w\)值合成一个,
很容易发现,可以用\(b_i\)来代表值为\(i\)\(w\)有多少个,然后从\(1\)开始扫,对\(b_i\)\(\log\)
具体实现:
容易发现若\(\log b_i=x\),那么我们将\(b_i\)减去\(x\),同时将\(b_{i+x}\)的值加\(1\),如此循环,直至\(b_i\)\(1\)\(0\),这样可以保证利益最大化。
最后从\(0\)到最大值扫一遍,如果有取值就将答案\(+1\)
这样的复杂度是\(\mathcal O(n\log n)\),可以通过本题。
毕竟是\(A\)题,实现起来就十分\(naive\)了,不过我码风有点毒瘤啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 1000035
int n;
int b[MAXN]={0},a,maxn=0;
int g[30];
int log2(int x){return floor(log(x)/log(2));}
int main()
{
	#define read(x) scanf("%d",&x)
	read(n);
	g[0]=1;
	for(int i=1;g[i-1]<1000000;i++) g[i]=g[i-1]*2;
	for(int i=1;i<=n;i++) read(a),b[a]++,maxn=max(maxn,a);
	for(int i=0;i<=maxn;i++)
	{
		if(!b[i]) continue;
		int x;
		while(b[i]>1)
		{
			x=log2(b[i]);
			b[i+x]++;
			maxn=max(maxn,i+x);//有可能会出现新的最值,要注意
			b[i]-=g[x];
		}
	}
	for(int i=0;i<=maxn;i++) if(b[i]) b[maxn+1]++;
	return printf("%d\n",b[maxn+1]),0;
}

给个赞呗~

猜你喜欢

转载自www.cnblogs.com/tlx-blog/p/12600747.html