gym 100520 C. Catalian Sequences
阿新 • • 發佈:2018-11-19
bfs打表,狀態數有點多,需要剔除掉無用的狀態才不會t。
i——當前序列長度
A——題目中所給,相鄰的兩個數ai+1 > ai的個數
low——下次新增數最低從哪個開始
s——用了哪些數
last——上一個以哪個數結尾。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MX = 2e4+7; ll ret[33]; struct node{ int i,A,low,last; ll s; node(){} node(int i, int A, int low, ll s, int last) : i(i), A(A), low(low), s(s), last(last){} bool operator < (const node &t) const{ if(i != t.i) return i < t.i; if(A != t.A) return A < t.A; if(low != t.low) return low < t.low; if(s != t.s) return s < t.s; return last < t.last; } //去掉多餘的狀態, void get_s() { ll t = (1<<low) - 1; s -= (s&t); } }; inline int get_low(ll s, int k, int low) { s &= (1<<k)-1; for(int i = k-1; i >= low; --i) if((s>>i)&1) return i; return low; } void init() { ret[1] = 1; queue<node> que; map<node,ll> ans; //0 0 node u = node(2,0,0,1,0); que.push(u); ans[u] = 1; //0 1 u = node(2,1,0,3,1); que.push(u); ans[u] = 1; while(que.size()) { node u = que.front(); que.pop(); ret[u.i] += ans[u]; if(u.i >= 32) continue; node v; for(int k = u.low; k <= u.A+1; k++) { int tmpA = (k > u.last? u.A+1 : u.A); v = node(u.i+1, tmpA, get_low(u.s,k,u.low), u.s|(1<<k), k); v.get_s(); if(!ans.count(v)) { que.push(v); ans[v] = ans[u]; } else ans[v] += ans[u]; } } } int main() { #ifdef LOCAL //freopen("input.txt","r",stdin); #else freopen("catalian.in","r",stdin); freopen("catalian.out","w",stdout); #endif // LOCAL init(); int n,cas = 0; while(~scanf("%d",&n) && n){ printf("Case #%d: %lld\n",++cas,ret[n]); } return 0; }