Description
Once upon a time, there was a maze. The shape of the maze was like a tree with roots. Each node (except for the leaf node) had exactly K sons.
At the beginning, you are at the root node. The K sons of the root node are marked as' A ',' B ',' C ' , and the K son nodes of node 'A' are marked as' AA ',' AB ',' AC ' , and so on. This tree has A total of L layers.
Now you know in advance that there is gold in M nodes, and you can send N robots to collect gold. First of all, you can specify the target nodes of each robot, so these robots will collect all the gold from the root node to the target node (including the target node), but the gold at each location can only be collected once.
Now you need to work out a goal allocation plan to get the most gold.
Title Solution
First, we rank m nodes from small to large So we need to make trees, in fact, we only need to connect these gold nodes together We found 2~m's father (or grandfather or great grandfather or great grandfather or great grandfather...) (use!! Two points!! Implementation), stored in the queue At last, dp Let's take f[i][j] as the root of the ith node, and use the j-th robot to collect the maximum number of gold The equation of state transition is f[x][i]=max(f[x][i],f[x][i-j]+f[y][j]) (Ps: x is the current node, i is the currently enumerated robot, y is the next generation node, j is the next generation node)
Code
uses math;
type strx=string[55];
var num,m,k,l,n,x,i,j:longint;
next,last,first,bz:array[0..50050]of longint;
a:array[0..50050]of strx;
f:array[0..50050,0..50]of longint;
w:string;
procedure insert(i,j:longint);
begin
inc(num);
next[num]:=last[i];
last[i]:=num;
first[num]:=j;
end;
procedure qsort(l,r:longint);
var i,j:longint;
mid,t:strx;
begin
if (l>=r) then exit;
i:=l; j:=r; mid:=a[(l+r) div 2];
repeat
while (a[i]<mid) do inc(i);
while (a[j]>mid) do dec(j);
if (i<=j) then
begin
t:=a[i]; a[i]:=a[j]; a[j]:=t;
inc(i); dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
function find(x:strx):longint;
var l,r,mid:longint;
begin
l:=1; r:=i;
while (l<r) do
begin
mid:=(l+r)div 2;
if (a[mid]<x)then l:=mid+1 else r:=mid;
end;
if (a[l]<>x) then exit(0) else exit(l);
end;
procedure dp(x:longint);
var k,y,i,j:longint;
begin
k:=last[x];
while (k<>0) do
begin
y:=first[k];
dp(y);
for i:=n downto 1 do
for j:=1 to i do
f[x,i]:=max(f[x,i],f[y,j]+f[x,i-j]);
k:=next[k];
end;
for i:=1 to n do f[x,i]:=f[x,i]+bz[x];
end;
begin
readln(m,k,l,n);
for i:=1 to m do readln(a[i]);
inc(m);
a[m]:='';
qsort(1,m);
x:=1;
for i:=2 to m do
begin
w:=a[i];
delete(w,length(w),1);
j:=find(w);
while (j=0) do
begin
delete(w,length(w),1);
j:=find(w);
end;
insert(j,i);
bz[i]:=1;
end;
dp(1);
writeln(f[1,n]);
end.