专栏文章
题解:CF1198A MP3
CF1198A题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqib5uf
- 此快照首次捕获于
- 2025/12/04 05:16 3 个月前
- 此快照最后确认于
- 2025/12/04 05:16 3 个月前
题目传送门
思路
注意到题目给了 (内存),可以直接逆向求出 的最大值,因为我们需要最小的删除数量,显然此时 个不同为最优。
所以我们只需要考虑尽量删除数量更少的强度值就ok了。题目中允许 的复杂度,删除时需要确定 删除两边,一眼双指针(区间)实现。
用桶记录相同强度的音频,可以确定中间有 个不同值,枚举时两边同时加,中间的和取最大值,这样删除的就最小了。
注意
- 的最大值为 ,计算时特判防止过大,如果超过范围随便存。
- 如果强度不同数量在开始时就不及最大值,根本不需要删除,直接结束。
Code
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,x,y) for(i=x;i<=y;i++)
int a,n,k,I,ans,sum;
set<int> s;
map<int,int> m;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int i;
cin>>n>>I;
if(I*8/n>=31) //特判
{
cout<<0;
return 0;
}
k=1<<(I*8/n);//计算最大值
F(i,1,n) //输入,计数
{
cin>>a;
m[a]++;
s.insert(a);
}
if(s.size()<=k) cout<<0;
else
{
auto r=s.begin(),l=s.begin();
F(i,1,k)//初始化和
{
sum+=m[*r];
r++;
}
while(r!=s.end())//双指针枚举
{
sum=sum-m[*l]+m[*r];
l++,r++;
ans=max(ans,sum);
}
cout<<n-ans;//输出答案
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...