专栏文章

题解:CF1198A MP3

CF1198A题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqib5uf
此快照首次捕获于
2025/12/04 05:16
3 个月前
此快照最后确认于
2025/12/04 05:16
3 个月前
查看原文

题目传送门

思路

注意到题目给了 II(内存),可以直接逆向求出 KK 的最大值,因为我们需要最小的删除数量,显然此时 KK 个不同为最优。
所以我们只需要考虑尽量删除数量更少的强度值就ok了。题目中允许 O(n)O(n) 的复杂度,删除时需要确定 l,rl,r 删除两边,一眼双指针(区间)实现。
用桶记录相同强度的音频,可以确定中间有 KK 个不同值,枚举时两边同时加,中间的和取最大值,这样删除的就最小了。

注意

  1. KK 的最大值为 nn ,计算时特判防止过大,如果超过范围随便存。
  2. 如果强度不同数量在开始时就不及最大值,根本不需要删除,直接结束。

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 条评论,欢迎与作者交流。

正在加载评论...