1. 程式人生 > >51nod1780 完美序列

51nod1780 完美序列

while begin 沒有 repeat ogr const nbsp gin sort

  首先我們需要排個序,如果排序之後相鄰兩項差超過1就是無解。統計一下每個數出現的次數num[i]。

  然後我們很容易發現,一個完美序列,去掉所有權值大於某個值的數之後,還是完美的。

  這樣我們就考慮一路dp過去,將每一種數插進去。然後發現,當前數的決策之和上一個數有關。我們插的位置實際上只有兩種可能:兩邊都是上一種數,一邊是上一種數而且另一邊沒有數。這樣狀態比較好記錄,只要記錄上一種數有多少個連續的段和有有沒有放在左右兩邊就好了。假如第i種數被分成了x段,考慮第一種情況,那就可以轉移到第i+1種數被分成1..x-num[i]段,組合數算一下,應該比較好搞。有沒有放在左右兩邊也可以討論,非常簡單。可以參考代碼。

技術分享
 1 program j01;
 2 const maxn=30086;mo=1000000007;
 3 var a:array[0..maxn]of longint;
 4     c:array[0..200,0..200]of int64;
 5     num:array[0..maxn]of longint;
 6     cnt,i,j,k,n,sp:longint;
 7     ans:int64;
 8     f:array[0..maxn,0..100,0..3]of int64;
 9 
10 procedure sort(l,r:longint);
11 var i,j,x,y:longint;
12 begin
13 i:=l;j:=r;x:=a[(i+j)div 2]; 14 repeat 15 while a[i]<x do inc(i); 16 while x<a[j] do dec(j); 17 if i<=j then 18 begin 19 y:=a[i];a[i]:=a[j];a[j]:=y; 20 inc(i);dec(j); 21 end; 22 until i>j; 23 if i<r then sort(i,r); 24 if l<j then sort(l,j);
25 end; 26 27 procedure pre; 28 var i:longint; 29 begin 30 sort(1,n); 31 cnt:=1;num[1]:=1; 32 for i:=2 to n do 33 begin 34 if a[i]-a[i-1]>1 then 35 begin 36 writeln(0);halt; 37 end; 38 if a[i]<>a[i-1] then inc(cnt); 39 inc(num[cnt]); 40 end; 41 c[0,0]:=1; 42 for i:=1 to 200 do 43 begin 44 c[i,0]:=1; 45 for j:=1 to i do c[i,j]:=(c[i-1,j]+c[i-1,j-1])mod mo; 46 end; 47 end; 48 49 begin 50 readln(n); 51 for i:=1 to n do read(a[i]); 52 pre; 53 f[1,1,3]:=1; 54 for i:=1 to cnt-1 do 55 begin 56 for j:=1 to num[i] do 57 begin 58 sp:=num[i]-j; 59 if f[i,j,0]>0 then 60 for k:=1 to sp do 61 f[i+1,k,0]:=(f[i+1,k,0]+f[i,j,0]*c[sp,k]mod mo*c[num[i+1]-1,k-1]mod mo)mod mo; 62 if f[i,j,1]>0 then 63 begin 64 for k:=1 to sp do 65 f[i+1,k,0]:=(f[i+1,k,0]+f[i,j,1]*c[sp,k]mod mo*c[num[i+1]-1,k-1]mod mo)mod mo; 66 for k:=0 to sp do 67 f[i+1,k+1,1]:=(f[i+1,k+1,1]+f[i,j,1]*c[sp,k]mod mo*c[num[i+1]-1,k]mod mo)mod mo; 68 end; 69 if f[i,j,2]>0 then 70 begin 71 for k:=1 to sp do 72 f[i+1,k,0]:=(f[i+1,k,0]+f[i,j,2]*c[sp,k]mod mo*c[num[i+1]-1,k-1]mod mo)mod mo; 73 for k:=0 to sp do 74 f[i+1,k+1,2]:=(f[i+1,k+1,2]+f[i,j,2]*c[sp,k]mod mo*c[num[i+1]-1,k]mod mo)mod mo; 75 end; 76 if f[i,j,3]>0 then 77 begin 78 for k:=1 to sp do 79 f[i+1,k,0]:=(f[i+1,k,0]+f[i,j,3]*c[sp,k]mod mo*c[num[i+1]-1,k-1]mod mo)mod mo; 80 for k:=0 to sp do 81 f[i+1,k+1,1]:=(f[i+1,k+1,1]+f[i,j,3]*c[sp,k]mod mo*c[num[i+1]-1,k]mod mo)mod mo; 82 for k:=0 to sp do 83 f[i+1,k+1,2]:=(f[i+1,k+1,2]+f[i,j,3]*c[sp,k]mod mo*c[num[i+1]-1,k]mod mo)mod mo; 84 for k:=2 to sp+2 do 85 f[i+1,k,3]:=(f[i+1,k,3]+f[i,j,3]*c[sp,k-2]mod mo*c[num[i+1]-1,k-1]mod mo)mod mo; 86 end; 87 end; 88 end; 89 ans:=0; 90 for i:=1 to num[cnt] do 91 ans:=(ans+f[cnt,i,0]+f[cnt,i,1]+f[cnt,i,2]+f[cnt,i,3])mod mo; 92 writeln(ans); 93 end.
View Code

51nod1780 完美序列