首页 > 其他分享 >hdu:Ice Cream Tower(构造二分)

hdu:Ice Cream Tower(构造二分)

时间:2023-05-26 17:22:32浏览次数:48  
标签:二分 hdu 座塔 int cnt Ice leq 2b Tower

一座高度为k的塔\(b1,b_2,\dots,b_k\)满足\(2b_1\leq b_2,2b_2\leq b_3,2b_3\leq b_4,\dots,2b{k-1}\leq b_k\)

你要从中选择一些数来叠很多座高度为\(k\)的塔,问最多能叠多少座塔。

Input
第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。

每组数据第一行包含两个正整数n,k(2≤n≤100000,2≤k≤30)。

第二行包含\(n\)个正整数\(a_1,a_2,\dots,a_n(1\leq a_i\leq 10^9)\)。

Output
对于每组数据输出一行一个整数,即能叠出的塔的数量。

输入样例
3
4 2
1 2 3 4
6 3
1 1 2 2 4 4
6 3
1 1 2 2 3 4
输出样例
2
2
1

数学--构造二分

因为若能够搭出x座塔,必然可以搭出x-1座塔,直接二分查找最大的x即可,关键在判断能否搭成x座k层高的塔,贪心枚举即可
注意无解的特判,让二分范围在[1,n]

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,k;
int a[N];

bool f(int x)//返回能否叠出x座k层塔
{
	//利用贪心分析:如能够搭出x座塔,用最小的x个ai座塔底一定是一个解
	vector<int> v[x+1];
	int cnt=0;
	for(int i=1;i<=n;++i)
	{
		cnt%=x;
		if(v[cnt].empty()||a[i]>=2*v[cnt].back())
		{
			v[cnt].push_back(a[i]);
			cnt++;
		}
		//cout<<v[0].size()<<' '<<v[1].size()<<'\n';
	}
	for(int i=0;i<x;++i) if(v[i].size()<k) return false;
	return true;
}

int bina(int mi,int ma)//二分的目的:找到最大的x使得f(x)=true
{
	int l=mi,r=ma,ans=r;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		bool tmp=f(mid);
		if(tmp) ans=mid,l=mid+1;
		else r=mid-1;
	}
	return ans;
}

void solve()
{
    cin>>n>>k;
    for(int i=1;i<=n;++i) cin>>a[i];
    sort(a+1,a+1+n);
    if(!f(1)) cout<<'0'<<'\n';//特判一下无解的情况因为x不能做被模数
    else
    cout<<bina(1,n/k)<<'\n';
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        solve();
    }
    return 0;
}

标签:二分,hdu,座塔,int,cnt,Ice,leq,2b,Tower
From: https://www.cnblogs.com/ruoye123456/p/17435317.html

相关文章

  • hdu:序列划分(构造二分)
    ProblemDescription给定\(n\)个正整数\(a_1,a_2,\dots,a_n\),将这个序列从左到右划分成\(m\)段,使得每段至少有一个数。你需要让数字之和最大的那一段的数字和尽可能得小。Input第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。每组数据第一行包含两个正整数n,m(1≤m≤......
  • HDU 1176 免费馅饼(简单动态规划)
    传送门这道题是中文描述的,我相信大家都肯定能够看得懂(滑稽),思路上呢大概就是一个升级版的数塔(点我去看数塔)既然是动态规划问题所以首先肯定要先找出来状态转移方程,我找到的状态转移方程就是a[i][j]+=max(max(a[i+1][j+1],a[i+1][j]),a[i+1][j-1]),其中a[i][j]就是表示第i时刻在k位......
  • HDU 1029 Ignatius and the Princess IV(基础dp)
    传送门题目大意就是给你n个数(保证n为一个奇数),存在一个数出现的次数大于(n+1)/2次,求这个数;这个数出现的次数比其他数出现的次数加起来还多,那么当这个数出现时+1,其他的数出现时-1,最后得到的数为正数。假定一个数为特殊数,若当前数与特殊数相同则cnt++,若不相同则cnt--,如果这时cnt<0,用当......
  • HDU 2084 数塔(动态规划入门)
    传送门中文题就不给大家翻译了(手动滑稽),反正大家都看得懂。这是一道动态规划入门的题目,只需要找出状态转移方程即可。状态方程:dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j])(dp[i][j]表示从第i层第j个数开始搜能得到的最大数)代码如下:#include<cstring>#include<iostream>#include<......
  • HDU 1024 Max Sum Plus Plus(动态规划)
    传送门题意是给你个数字序列,现在让你把这个序列分成m个连续的子序列,且要求这m个子序列的累加和最大。思路:这道题的题意可以理解为问在序列为末尾时,把序列分为m个子序列这个状态时的最大累加和,那么可以得出这个状态应该是由上一个状态转移得来:(因为dp[i][j]表示数到第j个字符时,前j个......
  • CodeForces 1108C Nice Garland(DFS)
    传送门题目大意就是给你一个由'R','G','B'三个字母组成的字符串,然后这个字符串需要满足任意相邻的三个字符不能相同,如果不满足则需要你对其进行更改,然后输出更改的次数和更改完的字符串。具体的思路就是枚举"RGB"这三个的组合,显然只有3!个,然后依次计算步数代码如下#include<iostream>......
  • Linxu解决systemctl启动服务失败,Error: No space left on device
    查看磁盘空间实际占用情况查看磁盘inodes占用情况这两部发现都没有问题。要是哪里发现被沾满了,直接删除解放空间。此篇是讲另一种情况。查看默认inotify的max_user_watches值[root@VM-4-4-centosnginx]#sysctlfs.inotifyfs.inotify.max_queued_events=16384fs.inotif......
  • ceph config get mgr 和 ceph mgr services 显示的内容不一致怎么办
    root@ceph-deploy:~#cephconfiggetmgrWHOMASKLEVELOPTIONVALUEROmgradvancedmgr/dashboard/ceph-mgr1/server_addr10.0.0.104*mgradvancedmgr/dashboard/ceph-mgr1/server_port9019*......
  • FLEX实践—XML HttpService加载错误
    主应用代码:<?xmlversion="1.0"encoding="utf-8"?><mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center" verticalAlign="middle" creationComplete="init......
  • idea显示springboot多服务启动界面service
    如果是多模块的微服务,idea提供了一个可以多服务启动的界面services,如果你的项目里没看到这个界面:那么你需要在顶级的maven工程中找到这个配置,然后找到componentname="RunDashboard"这个节点整个替换掉:<componentname="RunDashboard"><optionname="configurationTypes">......