一道分析题
1,仔细分以后易得,对于给定的n与m,min {bj,1<=j<=m}是确定的
因为我们要保证它最大,所以把这n个元素平均分配成m份,答案ans1即为 [n/m]
2,再考虑如何调整序列的问题,显然,用到贪心思想
首先统计每个小于m的a[i]的个数b[a[i]].然后从1 到 n枚举每个a[i],若
a,a[i]>m,则调用find函数找到一个x,满足b[x]<ans1把a[i]更新成x,并更新b[x]的个 数即操作数ans2
b,b[a[i]]>ans1,同样调用find函数找到x,把a[i]更新成x,更新b[a[i]]、b[x]及 ans2.
总结:主要的问题是如何增加b[x]<ans1的x 的数量,显然,有两种方法
一个是用a[i]>m的数,另一个是用b[y]>ans1的y
反思:在拿到一道没有模板的题目时,先不要着急做,首先要仔细分析
program O_O;
var
i,j,k,n,m,x,ans1,ans2:longint;
a,b:array[0..2000] of longint;
procedure init;
var
i:longint;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i]);
if a[i]<=m then
inc(b[a[i]]);
end;
ans1:=n div m;
end;
function find:longint;
var
i:longint;
begin
for i:=1 to m do
if b[i]<ans1 then exit(i);
exit(maxlongint);
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do
begin
if a[i]>m then
begin
x:=find;
if x=maxlongint then continue;
a[i]:=x;
inc(b[a[i]]);
inc(ans2);
end
else if b[a[i]]>ans1 then
begin
x:=find;
if x=maxlongint then continue;
dec(b[a[i]]);
inc(b[x]);
a[i]:=x;
inc(ans2);
end;
end;
end;
procedure print;
var
i:longint;
begin
writeln(ans1,' ',ans2);
for i:=1 to n do
write(a[i],' ');
end;
begin
init;
main;
print;
end.