给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子
的限制,求有多少种方案。
标签:
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 using namespace std; 9 typedef long long LL; 10 const int MAXN = 201; 11 const int MOD = 100000000; 12 int n; 13 LL f[MAXN][50]; 14 int cnt[MAXN]; 15 //f[n]=(f[n-1]+f[n-2])*(n-1)表示错排方案数的递推公式,因为可以视为新添加两个点,如果前n-1个满足,那么这两个与其中任意一个互相交叉互换也一定满足;如果前n-2个满足,最后两个不满足,那么直接交叉也使得可以满足。 16 17 int main() 18 { 19 scanf("%d",&n); f[1][0]=0; f[2][0]=1; 20 for(int i=3;i<=n;i++) { 21 for(int j=0;j<=cnt[i-1];j++) f[i][j]=f[i-1][j]+f[i-2][j]; 22 cnt[i]=cnt[i-1]; for(int j=0;j<=cnt[i-1];j++) f[i][j+1]+=f[i][j]/MOD,f[i][j]%=MOD; 23 while(f[i][cnt[i]+1]) cnt[i]++; 24 for(int j=0;j<=cnt[i];j++) f[i][j]*=(i-1); 25 for(int j=0;j<=cnt[i];j++) f[i][j+1]+=f[i][j]/MOD,f[i][j]%=MOD; 26 while(f[i][cnt[i]+1]) cnt[i]++; 27 } 28 printf("%lld",f[n][cnt[n]]); 29 for(int i=cnt[n]-1;i>=0;i--) printf("%08lld",f[n][i]); 30 return 0; 31 }
标签:
原文地址:http://www.cnblogs.com/ljh2000-jump/p/5873230.html