列表

详情


NC233787. 分组(version 2)

描述

请注意,version 1 与 version 2 仅在存在数据范围上的区别。

有  个学生,第  个学生的成绩是 ,同时你会得到一个序列 

你要把这些学生分成若干组,使得每组的人数都为奇数,且每组的人数在  这个范围内。

设一组的学生成绩中位数为 ,且该组一共有  人,那么一组的分值就定义为 

定义一个分组方案的分值定义为所有组分值的平均数。

你需要找到一个分组方案使得这个方案的分值最大,并输出这个分值向下取整的结果。

输入描述

第一行三个整数  。

第二行  个整数  。

第三行  个整数 

输出描述

如果不存在任何一种分配方案,输出 

否则输出一个整数,表示答案向下取整的结果。

示例1

输入:

5 1 5
4 4 3 3 5
1 5 5 3 5

输出:

5

说明:

最优分组方式为 [5,3,3],[4],[4] 。

此时最大平均值为 \frac{16}{3},向下取整为 

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 158ms, 内存消耗: 6264K, 提交时间: 2022-04-16 13:10:38

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x; i<=y; ++i)

using namespace std;
const int N=100,INF=1000000000;
int n,l,r,a[N],b[N],f[2][N][N][N],tp,ans;

void chkmax(int &x,int y)
{
	if(x<y) x=y;
}

int getint()
{
	char ch;
	while(!isdigit(ch=getchar()));
	int x=ch-48;
	while(isdigit(ch=getchar())) x=x*10+ch-48;
	return x;
}

int main()
{
	n=getint(),l=getint(),r=getint();
	rep(i,1,n) a[i]=getint();
	rep(i,1,n) b[i]=getint();
	sort(a+1,a+1+n);
	rep(i,0,n) rep(j,0,n) rep(k,0,n) f[0][i][j][k]=-INF;
	f[0][0][0][0]=0;
	rep(p,1,n)
	{
		tp^=1;
		rep(i,0,n) rep(j,0,n) rep(k,0,n) f[tp][i][j][k]=-INF;
		rep(i,0,n) rep(j,0,n) rep(k,0,n) if(f[tp^1][i][j][k]>=0)
		{
			int x=f[tp^1][i][j][k];
			chkmax(f[tp][i][j+1][k],x);
			if(k) chkmax(f[tp][i][j][k-1],x);
			rep(len,l,r) if(len&1)
			{
				int y=(len+1)>>1;
				if(y-1>j) break;
				chkmax(f[tp][i+1][j-y+1][k+y-1],x+(a[p]^b[len]));
			}
		}
	}
	ans=-1;
	rep(i,1,n) if(f[tp][i][0][0]>=0) chkmax(ans,f[tp][i][0][0]/i);
	printf("%d\n",ans);
	return 0;
}

上一题