当前位置: 代码迷 >> 综合 >> Ice Cream Tower Gym - 101194D(贪心 二分)
  详细解决方案

Ice Cream Tower Gym - 101194D(贪心 二分)

热度:28   发布时间:2023-12-05 21:42:31.0

链接:Attachments - 2016-2017 ACM-ICPC CHINA-Final - Codeforces

题意:

给你一个n代表有多少重量的冰激凌块,再给你要求的冰激凌塔的层数,冰激凌塔的规则是下一个必须等于或者大于上一层的二倍

然后给你n个重量,问你最多可以完成需要的多少个冰激凌塔.

可以发现答案具有单调性。那么我们二分mid个塔,取最小mid个数为每个塔塔顶,接着对mid个塔一层一层填数,填不了就不符,填完了继续二分。

/*Keep on going Never give up*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pi acos(-1.0)
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
const int maxn=4e5+10;
int n,t,k,a[maxn],b[maxn];
bool cheak(int x){for(int i=1;i<=x;i++){b[i]=a[i];}int tt=x+1;for(int i=1;i<k;i++){for(int j=1;j<=x;j++){while(a[tt]<b[j]*2){tt++;if(tt>n)return 0;}b[j]=a[tt++];//	printf("b[%lld]: %lld\n",j,b[j]);}}return 1;
}
signed main(){ t=read();for(int ttt=1;ttt<=t;ttt++){n=read(),k=read();memset(a,0,sizeof(a));memset(b,0,sizeof(b));for(int i=1;i<=n;i++){a[i]=read();}if(k==1){cout<<"Case #"<<ttt<<": "<<n<<endl;continue;}sort(a+1,a+1+n);int l=0,r=n+1,mid;while(r-l>1){mid=(l+r)>>1;if(cheak(mid))l=mid;elser=mid;}printf("Case #%lld: %lld\n",ttt,l);}
}

唉,细节没处理好,改了一个小时。

  相关解决方案