The Review Plan I
题目链接
:点击打开链接
禁位棋盘知识:
点击打开链接
题意
: 有N个方块, Teemo每天只能取一块, 但Teemo在有些天不能取有些块, 问N天将方块取完的方案总数.
题解:
禁位棋盘的横轴纵轴分别表示天数和块数,
dfs搜索记录禁位棋盘多项式中不同禁位数量的可能数. 根据公式 N = w(0) - w(1) +w(2)-...+(-1)^N*w(N) 可以得到最终结果.
代码如下:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<iomanip>
#include<stdlib.h>
#include<cstdio>
#include<string>
#include<string.h>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int INF = 0x7fffffff;
const int MAX_N = 55;
const int MAX_M = 55;
void show(string a, int val){
cout<<a<<": "<<val<<endl;
}
//Define array zone
int N, M;
bool c[MAX_N];
bool chess[MAX_N][MAX_N];
int P[MAX_N];
ll fac; // factorial
const int MOD = 55566677;
//Cut-off rule
void dfs(int row, int cnt){
if(row>N){
P[cnt]++;
return;
}
for(int i=1; i<=N; i++){
if(chess[row][i]&&!c[i]){
c[i] = true;
dfs(row+1, cnt+1);
c[i] = false;
}
}
dfs(row+1, cnt);
}
void solve(){
dfs(1, 0);
fac = 1; ll res = 0;
int sym = N&1? -1: 1;
for(int i=0; i<=N; i++){
res = (res + sym*P[N-i] * fac+MOD)%MOD;
fac = (i+1)*fac %MOD;
sym*=-1;
}
printf("%d\n",res);
}
int main(){
while(~scanf("%d%d",&N, &M)){
memset(c,false,sizeof c);
memset(chess, false, sizeof chess);
memset(P, 0, sizeof P);
int a, b;
for(int i=0; i<M; i++){
scanf("%d%d",&a,&b);
chess[a][b] = true;
}
solve();
}
}