P8587 新的家乡 题解

1|0题意

给定 n 个高度分别为 hi 的柱子,两个柱子能合并成一个 hi+hj 的新柱子,每根柱子至多被使用一次。

询问最多能建出多少根高度相同的柱子,并且最优答案下柱子的高度有多少种情况。

1n1061hi3×103

2|0思路

2|1爆搜!

  • 首先我们想,如果我们 n2 正向枚举有多少种方案数,显然会超时。

  • 怎么办呢!我们看到 1hi3×103 ,正难则反!我们直接设 f[i] 表示柱子高度为 i 时能有多少根不就行了吗,给一个 mp[i] 数组存储高度为 i 的柱子有多少根,然后直接 O(h2) 枚举就能过了。

  • 最后给方案数排序,输出最大的有多少根柱子,再看有多少种高度跟他一样就行了。

3|0代码实现

#include<bits/stdc++.h> //#define int long long #define ll long long #define next nxt #define re register #define il inline const int N = 3e4 + 5; using namespace std; int max(int x,int y){return x > y ? x : y;} int min(int x,int y){return x < y ? x : y;} int n,ans; int mp[N],f[N<<1]; int Max=-1,Min=1e9;/*这些柱子的最小和最大高度*/ il int read() { int f=0,s=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) f |= (ch=='-'); for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48); return f ? -s : s; } il bool mysort(int a,int b) { return a > b; } signed main() { n=read(); for(re int i=1;i<=n;i++) { int x = read();mp[x]++;/*存高度,更新最大高度最小高度*/ Max=max(x,Max),Min=min(x,Min); } for(re int i=Min*2;i<=Max*2;i++)/*合并后最小的高度肯定就是高度最小的柱子乘以2,最大的高度亦然*/ { for(re int j=1;j<=Max*2;j++) { if(j*2 > i) break;/*前面一半已经计算了后面的一半了,所以直接break*/ if(i-j == j) f[i] += mp[j]/2;/*两个相等的柱子相加,那么根数加上总共的一半*/ else f[i] += min(mp[j],mp[i-j]);/*两个柱子高度不相同,那么就能配凑出两个柱子数量较小的那一个*/ } } sort(f+1,f+Max*2+1,mysort);/*从大到小排序*/ printf("%d ",f[1]);/*输出最多根数*/ int Maxx = f[1]; for(int i=1;i<=Max*2+1;i++) { if(f[i] == Maxx) ans++;/*判断有多少数量相等*/ else break; } printf("%d",ans);/*输出高度不同的方案数*/ } }

时间复杂度 O(h2) ,可以通过。


__EOF__

本文作者bloodstalk
本文链接https://www.cnblogs.com/bloodstalk/p/17433078.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Bloodstalk  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示