BZOJ——T 4563: [Haoi2016]放棋子

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 387  Solved: 247
[Submit][Status][Discuss]

Description

给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子
的限制,求有多少种方案。
 

Input

第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例
 

Output

一个整数,即合法的方案数。

Sample Input

2
0 1
1 0

Sample Output

1

HINT

 

Source

 错排公式( f[i]=f[i-1]+f[i-2] )* (i-1) + 高精度(压位)
 1 #include <cstdio>
 2 
 3 const int mod(10000);
 4 const int N(5233);
 5 const int P(4);
 6 int n;
 7 
 8 #define max(a,b) (a>b?a:b)
 9 struct Num {
10     int num[10000];
11 //    Num() { for(int i=1; i<N; ++i) num[i]=0; num[0]=1; }
12     void print()
13     {
14         printf("%d",num[num[0]]);
15         for(int i=num[0]-1; i; --i)
16             printf("%0*d",P,num[i]);
17     } 
18 }ans[N];
19 inline void Add(Num a,Num b)
20 {
21 //    ans[0]=Num();
22     ans[0].num[0]=max(a.num[0],b.num[0]);
23     for(int i=1,x=0; i<=ans[0].num[0]; ++i)
24     {
25         ans[0].num[i]=a.num[i]+b.num[i]+x;
26         if(ans[0].num[i]>=mod)
27         {
28             x=ans[0].num[i]/mod;
29             ans[0].num[i]%=mod;
30             ans[0].num[0]=max(ans[0].num[0],i+1);
31         }
32         else x=0;
33     }
34     for(; !ans[0].num[ans[0].num[0]]&&ans[0].num[0]; ) ans[0].num[0]--;
35 }
36 Num Mul(Num a,int x)
37 {
38     for(int ove=0,i=1; i<=a.num[0]; ++i)
39     {
40         a.num[i]=a.num[i]*x+ove;
41         if(a.num[i]>=mod)
42         {
43             ove=a.num[i]/mod;
44             a.num[i]%=mod;
45             a.num[0]=max(i+1,a.num[0]);
46         }
47         else ove=0;
48     }
49     for(; !a.num[a.num[0]]&&a.num[0]; ) a.num[0]--;
50     return a;
51 }
52 
53 inline void read(int &x)
54 {
55     x=0; register char ch=getchar();
56     for(; ch>'9'||ch<'0'; ) ch=getchar();
57     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
58 }
59 
60 int Presist()
61 {
62 //    freopen("firstmeet.in","r",stdin);
63 //    freopen("firstmeet.out","w",stdout);
64     read(n);
65     ans[1].num[0]=ans[2].num[0]=1;
66     ans[1].num[1]=0; ans[2].num[1]=1;
67     for(int i=3; i<=n; ++i)
68     {
69         Add(ans[i-1],ans[i-2]);
70         ans[i]=Mul(ans[0],i-1);
71     }
72     ans[n].print();
73     return 0;
74 }
75 
76 int Aptal=Presist();
77 int main(){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7552353.html