vijos 1085 Sunnypig闖三角關

{這個題5個正確,五個超時,不要盲目相信個人代碼,誰有更好的算法或者優化請留言,(*^__^*) 嘻嘻……}算法

背景

貪玩的sunnypig請Charles爲他打造一個奇幻世界,Charles欣然答應了。然而一貫善於出難題的Charles是決不會輕易讓sunnypig輕鬆擁有一個奇幻世界的,因而Charles在建造過程當中設置了重重機關,只有在sunnypig破解了這些障礙以後,才能嘗試到奇幻世界中最有玩頭的終極寶貝——時空穿梭機。雖然奇幻世界中其餘的寶貝也頗有趣,但貪玩的sunnypig怎能放過打boss的機會呢?因而他開始了破解障礙的旅程。測試

描述

第二道障礙來源於一種古老的數學發現——楊輝三角,不過應該是倒過來的楊輝三角。若給出1~n的一個排列A,則將A一、A2相加,A二、A3相加……An-一、An相加,則獲得一組n-1個元素的數列B;再將B一、B2相加,B二、B3相加,Bn-二、Bn-1相加,則獲得一組n-2個元素的數列……如此往復,最終會得出一個數T。而Charles給sunnypig出的難題即是,給出n和T,再儘量短的時間內,找到能經過上述操做獲得T且字典序最小的1~n的排列。通過漢諾塔問題的訓練,sunnypig開始沉着的思考。。。優化

格式

輸入格式

本題有多組數據,對於每組數據:
一行兩個整數n(0<n<=20),t即最後求出來的數。ui

用文件結尾符判斷輸入結束。spa

輸出格式

對於每組測試數據輸出一行n個整數,用空格分開,行尾無多餘空格,表示求出來的知足要求的1~n的一個排列。code

 

解題思路

由題意得,有兩個數a,b時,t=a+b;blog

              有三個數a,b,c 時 t=a+2b+c排序

              有四個數a,b,c,d時 t=a+3b+3c+d數學

              ……it

             不可貴出,符合楊輝三角

因而,能夠枚舉每一個係數後的值,而後進行相加,作適當的剪枝,能夠得出答案

有人說是用排序不等式作,惋惜本人是一枚學渣兼蒟蒻,即便看到那個所謂a^2+b^2+c^2>=ab+ac+bc也不知道該怎麼用......

 
   
 1 program yanghui;
 2 var n,i,j,sum,t,flag:longint;
 3     a:array[0..20,0..20] of longint;
 4     b:array[0..20] of longint;
 5     s:array[0..20] of longint;
 6     pd:Array[1..20] of boolean;
 7 procedure yanghui;//求出楊輝三角
 8 var i,j:longint;
 9 begin
10  a[1,1]:=1;
11  for i:=2 to 20 do
12    begin
13     for j:=1 to i do
14     begin
15       a[i,j]:=a[i-1,j]+a[i-1,j-1];
16     end;
17    end;
18 end;
19 procedure dfs(n,k:longint);
20 var i:Longint;
21 begin
22     if flag=1 then exit;//如已經有答案,退出
23     if sum>t then exit;//如已經超過所求值,退出
24     if sum+(s[n]-s[k-1])*n<t then exit;//如不可能達到所求值,退出
25     if (k-1>(n+1) div 2) and(b[n-k+2]>b[k-1]) then exit;//如後面的值比對應位置的值大,退出(由於此時不是字典序最前的值)
26     if k=n+1 then
27     begin
28         if sum=t then
29         begin
30             for i:=1 to n do write(b[i],' ');
31             writeln;
32             flag:=1;
33         end;
34         exit;
35     end;
36     for i:=1 to n do//簡單回溯尋找答案
37     if (not pd[i]) then
38     begin
39         sum:=sum+i*a[n,k];
40         b[k]:=i;
41         pd[i]:=true;
42         dfs(n,k+1);
43         if flag=1 then exit;
44         sum:=sum-i*a[n,k];
45         pd[i]:=false;
46     end;
47 end;
48 
49 begin
50     yanghui;
51     while not eof do
52     begin
53         fillchar(pd,sizeof(pd),false);
54         flag:=0;
55         sum:=0;
56         read(n,t);
57         for i:=1 to n do s[i]:=s[i-1]+a[n,i];//前綴和,表示第n行前i個楊輝三角上的數值之和
58         dfs(n,1);
59     end;
60 end.
相關文章
相關標籤/搜索