CF293B Distinct Paths 搜索


傳送門


首先數據范圍很假

\(N + M - 1 > K\)的時候就無解

所以對於所有要計算的情況,\(N + M \leq 11\)

超級小是吧,考慮搜索

對於每一個格子試填一個數

對於任意道路上不能存在兩個相同顏色的限制使用狀態壓縮進行判斷

一些必要的剪枝:

①如果當前可以放的顏色比路徑長度要短,表示剩余顏色不夠,直接return

②如果當前這一個格子為空,並且填入的是在這之前從來沒有使用過的顏色,那么對於所有沒有使用過的顏色,它們填在這一個格子的答案是一樣的,只要搜一次就可以了。

#include<bits/stdc++.h>
#define lowbit(x) ((x) & -(x))
//This code is written by Itst
using namespace std;

inline int read(){
	int a = 0;
	char c = getchar();
	bool f = 0;
	while(!isdigit(c) && c != EOF){
		if(c == '-')
			f = 1;
		c = getchar();
	}
	if(c == EOF)
		exit(0);
	while(isdigit(c)){
		a = a * 10 + c - 48;
		c = getchar();
	}
	return f ? -a : a;
}

const int MOD = 1e9 + 7;
int arr[11][11] , f[11][11] , cnt1[1 << 10] , times[11];
int N , M , K;

int dfs(int x , int y){
	if(y > M){
		y = 1;
		++x;
	}
	if(x > N)
		return 1;
	int s = f[x - 1][y] | f[x][y - 1] , sum = 0 , calc = 0;
	if(K - cnt1[s] < N - x + M - y + 1)
		return 0;
	bool ff = 0;
	for(int i = 0 ; i < K ; ++i)
		if(!(s & (1 << i)))
			if(arr[x][y] == i + 1 || arr[x][y] == 0){
				f[x][y] = s | (1 << i);
				if(!times[i + 1]++){
					if(!ff){
						calc = dfs(x , y + 1);
						ff = 1;
					}
					sum = (sum + calc) % MOD;
				}
				else
					sum = (sum + dfs(x , y + 1)) % MOD;
				--times[i + 1];
			}
	return sum;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in","r",stdin);
	//freopen("out","w",stdout);
#endif
	N = read();
	M = read();
	K = read();
	if(N + M - 1 > K){
		puts("0");
		return 0;
	}
	for(int i = 1 ; i <= N ; ++i)
		for(int j = 1 ; j <= M ; ++j)
			++times[arr[i][j] = read()];
	for(int i = 1 ; i < 1 << K ; ++i)
		cnt1[i] = cnt1[i - lowbit(i)] + 1;
	cout << dfs(1 , 1);
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM