14个格子13张扑克牌(从A,2,3,4,...J,Q,K),目标状态是第一个格子放A,第二个放2...第13个放K 第14个是空白。现在如果只有最后n格的顺序不符合要求(前边14-n格已经排好),问这n格有多少种初始状态是可以通过移动牌来达到目标状态,移动的规则是,如果空格前边的牌是i,那么可以将点数为i+1的牌移动到空格位置,(i+1原先的位置现在就是空格了)。由于n最大只有13,这么小的状态第一想法就是搜索,写完后发现10以内的都是秒出,10以上的慢一点,慢慢点吧,反正状态不多直接打表..结果bfs打表好像是爆掉了,重写了个dfs速度好像还更快点...搜索的时候我是倒推的,找到一张牌,如果它前一位刚好比它小1,那么这张牌可以与空格位交换变成一个新的状态,然后计数++,继续dfs...这样写10以上算的很慢,所以只好打表了......
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
int out[15]={0,1,2,5,14,47,189,891,4815,29547,203173,1548222,12966093,118515434};
char a[20];
ll ans;
int n,m,sum;
void dfs(char s[],int space)
{
char ss[20];
for (int i=0; i<n; i++)
{
strcpy(ss,s);
if (((i==0 && s[i]==14-n+1) || (i!=0 && s[i-1]+1==s[i]) ) && i!=space)
{
swap(ss[i],ss[space]);
ans++;
dfs(ss,i);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
// while(cin>>n)
// {
// for (int i=0; i<n; i++)
// a[i]=14-n+i+1;
// a[n]='\0';
// ans=1;
// dfs(a,n-1);
// cout<<ans<<endl;
// }
cin>>n;
cout<<out[n]<<endl;
return 0;
}