首页 > 其他分享 >CF1793E

CF1793E

时间:2024-11-18 19:30:12浏览次数:1  
标签:ch int max CF1793E read while ans

link

一道十分简明的序列题

题意简述

$n$ 个人,每个人都要给一个 $[ 1 ,m ]$ 之间的整数,且每个 $[ 1 , m ]$ 间的整数需至少给一个人。
每个人有一个阈值 $a_i$ ,若与第 $i$ 个人拥有相同数字的人数至少为 $a_i$ (包括自己),那么他就是高兴的。
多次询问,每次一个 $m$ ,求最多高兴人数。

解决方案

易证得:按 $a_i$ 排序,一定是从前往后一段一段分组。

设 $f_i$ 表示前 $i$ 个人都高兴,至多分为几段。
所以我们可以写出动态转移方程。

f[j]=f[i]=max( f[j]+1,f[i] )  (0<=j<=i-a[i]  a[i]<=j)
代码
#include<bits/stdc++.h>

using namespace std;

const int N=3e5+100;
int n,m;
int T; 
int a[N];
int f[N];
int ans[N];

int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

//2024/1/16
int main()
{
	m=read();
	for(int i=1;i<=m;i++)	a[i]=read();
	sort(a+1,a+m+1);//按a[i]排序,一定是从前往后一段一段分组。
	for(int i=1;i<=m;i++)
	{
		if(i>=a[i])
		{
			f[i]=f[i-a[i]]+1;
			ans[f[i]+m-i]=max(i,ans[f[i]+m-i]);
		}//高兴人数为i,整数范围至多为f[i]+m-i
		else	ans[m-a[i]+1]=max(i,ans[m-a[i]+1]);//高兴人数为i,整数范围至多为m-a[i]+1 
		f[i] = max(f[i], f[i - 1]);
	}//dp:f[i]=max{f[j]+1} (0<=j<=i-a[i]  a[i]<=j)
	for(int i=m;i>=1;i--)		ans[i]=max(ans[i],ans[i+1]);
	T=read();
	while(T--)
	{
		n=read();
		printf("%d\n",ans[n]);
	}
	return 0;
} 

标签:ch,int,max,CF1793E,read,while,ans
From: https://www.cnblogs.com/tangml/p/18553480

相关文章

  • CF1793E
    \(\text{Problem-1793E-Codeforces}\)\(\text{*2600}\)备注2024.10.19考试T2。考场未能想出正解,找到性质但没有根据性质往dp方面想,而是想通过多枚举状态找最优解,需要反思!简要题意有一个数列\(A\),我们需要将其分成若干组。对于一个\(i\),若\(i\)所在的分组中元素个......
  • CF1793E Velepin and Marketi
    首先发现,每个人过的题是不同的,所以我们不关心过了那些题目。我们要直接去求分成\(k\)组最多的通过数是不容易的。我们可以转换一下,求当\(i\)个题通过的时候__最多__分多少组。为什么记最多,因为化成\(k\)个组通过\(i\)题可以的情况下,我们可以任意合并两个组,保证依然可以......
  • CF1793E Velepin and Marketing 题解
    题目大意有\(n\)个读者,第\(i\)年他们要一起读\(k_i\)本书,每一本书至少要让一个人读,每一个人也只能读恰好一本书。如果某一个人\(j\),如果有\(a_j\)个人这一年里和他读了同一本书,那么他就会感到满足。对于所有的\(q\)组询问,每组给定一个\(k_i\),求感到满足的人数的最......
  • CF1793E Velepin and Marketing
    个人思路:从小到大排序,因为一定先满足小的,再满足大的。分组时,我们发现,同一组内的数在排序后的序列内连续,这样更优。因为(不会证)。我们预处理出对于每个出书数量的答案,查询......