「CF1342D Multiple Testcases」

Posted sxy_limit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CF1342D Multiple Testcases」相关的知识,希望对你有一定的参考价值。

题目大意

给出一个序列,和一些限制,需要将这个序列分到最少的组中使得每个组中大于 (i) 的数小于等于 (c_i) 个.

分析

先计算最小的组数考虑计算 (sum_i=sum_{i=j}^{n}(a_jgeq i)),计算过程类似一个后缀和,那么就可以直接计算出大于等于 (i) 的数至少要放在几组中,然后取max就好了.

然后考虑怎么去放,很显然是按顺序去放(从小到大排序后依次轮流放入)最优,可以保证一定满足,具体证明可以理解一下计算公式.

排序如果用桶排可以做到 (mathcal{O}(n+k)),但是我比较懒,就直接用了 sort.

代码

#include<bits/stdc++.h>
#define REP(i,first,last) for(int i=first;i<=last;++i)
#define DOW(i,first,last) for(int i=first;i>=last;--i)
using namespace std;
const int MAXN=2e5+5;
int n,k;
int arr[MAXN];
int c[MAXN];
int sum[MAXN];
int main()
{
	scanf("%d%d",&n,&k);
	REP(i,1,n)
	{
		scanf("%d",&arr[i]);
		sum[arr[i]]++;//统计出现次数
	}
	DOW(i,k-1,1)//后缀和
	{
		sum[i]+=sum[i+1];
	}
	int answer=0;
	sort(arr+1,arr+1+n);
	REP(i,1,k)
	{
		scanf("%d",&c[i]);
	}
	REP(i,1,k)
	{
		answer=max(answer,sum[i]/c[i]+(bool)(sum[i]%c[i]));//计算最小组数
	}
	printf("%d
",answer);
	REP(i,1,answer)
	{
		int now=i,p=0;
		while(now<=n)//考虑是按组数循环,先计算出个数再输出
		{
			++p;
			now+=answer;
		}
		printf("%d ",p);
		now=i;
		while(now<=n)
		{
			printf("%d ",arr[now]);
			now+=answer;
		}
		printf("
");
	}
	return 0;
}

以上是关于「CF1342D Multiple Testcases」的主要内容,如果未能解决你的问题,请参考以下文章

贪心/二分——cf1342D

[转]Wrapping multiple calls to SaveChanges() in a single transaction

hive 拉链表

电脑终止代码MULTIPLE

easyui的组合树怎么设置multiple

view UI 里面日期选择器多选 multiple 不生效