您的位置:首页 > 其它

Codeforces 283B Distinct Paths (dfs+剪枝)

2016-03-22 22:35 399 查看
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
using namespace std;

#define N 20
#define M 400030
#define mod 1000000007
#define B 234324
#define LL long long

int n, m, k;
int a

;
int f

;
int ans;

int getSta(int x, int y, int s) {
for(int i = x; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if((i == x && j < y)) continue;
if(a[i][j] == -1) continue;
s |= 1 << a[i][j];
}
}
return s;
}

bool check(int v, int x, int y) {
for(int i = x; i <= n; ++i) {
for(int j = y; j <= m; ++j) {
if(i == x && j == y) continue;
if(a[i][j] == v) return 0;
}
}
return 1;
}

int count1(int s) {
int ret = 0;
while(s) {
ret++; s -= s & -s;
}
return ret;
}
int dfs(int x, int y, int s) {
if(x == n + 1) {
return 1;
}
int dx = x, dy = y;
++dy; if(dy > m) dx++, dy = 1;
int t = f[x-1][y] | f[x][y-1];
if(a[x][y] != -1) {
int v = a[x][y];
if(t >> v & 1) return 0;
f[x][y] = t | (1 << v);
if(check(v, x, y))  {
return dfs(dx, dy, s | (1 << v));
}
else return 0;

}
else {
int ret = 0;
int w = 0;
int z = getSta(dx, dy, s);
while(z >> w & 1) ++w;
f[x][y] = t | (1 << w);
if(k != count1(z)) ret = 1LL * (k - count1(z)) * dfs(dx, dy, z | (1 << w)) % mod;
for(int i = 0; i < k; ++i) {
if(z >> i & 1 ^ 1) continue;
if(t >> i & 1) continue;
f[x][y] = t | (1 << i);
if(check(i, x, y))ret += dfs(dx, dy, s | (1 << i));
if(ret >= mod) ret -= mod;
}
return ret;
}
}

int main() {
scanf("%d%d%d", &n, &m, &k);
if(n + m - 1 > k) {
puts("0");
return 0;
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
scanf("%d", &a[i][j]);
--a[i][j];
}
}
ans = dfs(1, 1, 0);

printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: