题意
给你n个数的排列,找出一种排列方式使得他们用这种方式加起来的值为s
则将A1、A2相加,A2、A3相加……An-1、An相加,则得到一组n-1个元素的数列B;再将B1、B2相加,B2、B3相加,Bn-2、Bn-1相加,则得到一组n-2个元素的数列……直到只有一个数。
思路:
只需要找规律就可以知道他们的顺序权值关系是一个杨辉三角型了,然后用dfs搜索,不加优化40分,优化三方面,如下:
1.如果已经选的数大于你要求得了,就可以退出了。
2.如果你加入了这个数后,剩下的数组成的最大值比答案小,或最小值比答案大,那么也可以退出了。
3.以为杨慧三角形有对称性,所以到后面n div 2个的时候,所填的数一定要比前面对应的大,这样才满足字典序最小。
程序
const
maxn=20;
var
i,j,n,m,max,min:longint;
a:array [1..maxn,0..maxn] of longint;
h:array [1..maxn] of boolean;
he,lyt:array [-maxn..maxn] of longint;
flag:boolean;
procedure dfs(x,y:longint);
var
i,j,k,ii:longint;
begin
if flag then exit;
if (m=y) and (n<x) then
begin
for i:=1 to n do
write(he[i],' ');
writeln;
flag:=true;
exit;
end;
if x>n then exit;
if y>m then exit;
for i:=1 to n do
if (h[i]) then
begin
if (he[n-x+1]>i) and (x>n div 2+1) then continue;
h[i]:=false;
he[x]:=i;
j:=x+1;
k:=n;
max:=0;
for ii:=1 to n do
if h[ii]=true then
begin
if a[n,j]>a[n,k] then
begin
max:=max+ii*a[n,k];
dec(k);
end else
begin
max:=max+ii*a[n,j];
inc(j);
end;
end;
if max+i*a[n,x]<m-y then
begin
h[i]:=true;
continue;
end;
j:=x+1;
k:=n;
min:=0;
for ii:=n downto 1 do
if h[ii]=true then
begin
if a[n,j]>a[n,k] then
begin
min:=min+ii*a[n,k];
dec(k);
end else
begin
min:=min+ii*a[n,j];
inc(j);
end;
end;
if min+i*a[n,x]>m-y then
begin
h[i]:=true;
continue;
end;
dfs(x+1,y+i*a[n,x]);
h[i]:=true;
end;
end;
begin
assign(input,'easy.in'); reset(input);
assign(output,'easy.out'); rewrite(output);
a[1,1]:=1;
for i:=2 to maxn do
for j:=1 to maxn do
a[i,j]:=a[i-1,j]+a[i-1,j-1];
readln(n,m);
while (n<>0) and (m<>0) do
begin
flag:=false;
fillchar(h,sizeof(h),true);
dfs(1,0);
readln(n,m);
end;
close(input); close(output);
end.