题目链接: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;
}
给个赞呗~