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;
}