NC233787. 分组(version 2)
描述
请注意,version 1 与 version 2 仅在存在数据范围上的区别。
有 个学生,第
个学生的成绩是
,同时你会得到一个序列
。
你要把这些学生分成若干组,使得每组的人数都为奇数,且每组的人数在 这个范围内。
设一组的学生成绩中位数为 ,且该组一共有
人,那么一组的分值就定义为
。
定义一个分组方案的分值定义为所有组分值的平均数。
你需要找到一个分组方案使得这个方案的分值最大,并输出这个分值向下取整的结果。
输入描述
第一行三个整数
。
第二行
个整数
。
第三行
个整数
。
输出描述
如果不存在任何一种分配方案,输出
。
否则输出一个整数,表示答案向下取整的结果。
示例1
输入:
5 1 5 4 4 3 3 5 1 5 5 3 5
输出:
5
说明:
最优分组方式为 。
此时最大平均值为 ,向下取整为
。
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; }