Car II

Car II

Description

There is a chessboard with n m (n, m≤80, n m≤80), and k (k≤20) pieces should be placed on the board so that any two pieces are not adjacent. Find the total number of legal programs.

Input
n,m,k


Total number of output solutions

Sample Input

3 3 2

Sample Output

24

Ideas:
observation of the subject given the size, n, m≤80, SC in order to use this scale is difficult, 280 either in time or space can not afford
Yet we also see n * m≤80
little thought we can find : 9 * 9=81>80, that is, if n and m are both greater than or equal to 9, the condition of n * m≤80 will no longer be satisfied. Therefore, we have n or m less than or equal to 8, and 2 8 is acceptable! So we can use state pressure dp.

The title and the car is a bit like, but can only put a car is a line, and this problem but only restriction per row pieces per column is not adjacent car can enumerate the placement state of each line is still feasible. For car II, we use an s[] array to record the tot placement states of each row, s can be preprocessed with dfs in advance, and c[] is used to save the number of 1s in the i-th state to avoid repeated calculations

void dfs(ll  ans, ll  dep, ll  flag)
{
    
    
	if(dep > n) 
	{
    
    
		s[++tot]=ans;
		c[tot]=flag; 
		return;
	}
	dfs(ans, dep + 1, flag);
	dfs(ans + (1 << (dep - 1)), dep + 2, flag+1);
}

We use f [i] [j] [k] f[i][j][k]f [ i ] [ j ] [ k ] means theiiThe state of row i iss [j] s[j]s [ j ] and beforeiiPlace a total ofkk inrow ik pieces (pn pnp n replaceskkin the original questionk ) The number of plans. Follow the method of enumerating the current line scheme, as long as the placement scheme of the current line does not conflict with the previous line. Microscopically speaking, it means the state of two liness 1 s1s 1 ands 2 s2s 2 is not the same as1 1The bit of 1 , that is, s1&s2=0, in other words: s2 is the complement of s1.

Knowing the status of the i-th row, do you think it is enough? The problem also requires that any two pieces are not adjacent. So we have to include i-1. We get the recurrence:

Boundary: f [0] [1] [0] = 1; Boundary: f[0][1][0]=1; Side boundary : F [ 0 ] [ . 1 ] [ 0 ]=1;
f i , j , k = ∑ f i − 1 , p , k − c j f_{i,j,k}=\sum f_{i-1,p,k-c_j} fi,j,k=fi1,p,kcj
Finally, we just need to enumerate the tot placement methods of each row, and get the answer based on the principle of addition.

code:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);

using namespace std;

ll  n, m, K, c[10010], s[10010], tot, f[82][1<<9][21], ans;

void dfs(ll  ans, ll  dep, ll  flag)
{
    
    
	if(dep > n) 
	{
    
    
		s[++tot]=ans;
		c[tot]=flag; 
		return;
	}
	dfs(ans, dep + 1, flag);
	dfs(ans + (1 << (dep - 1)), dep + 2, flag+1);
}
int  main()
{
    
    
	scanf("%lld%lld%lld", &n, &m, &K);
	if(n > m)	swap(n, m);
	dfs(0, 1, 0);
	for(ll i=1; i<=tot; i++) f[1][s[i]][c[i]]=1;
	for(ll i=2; i<=m; i++)
		for(ll now=1; now<=tot; now++)
			for(ll last=1; last<=tot; last++)
				if(!(s[now] & s[last]))		
					for(ll k=0; k<=K; k++)
						if(k>=c[now])
							f[i][s[now]][k]+=f[i-1][s[last]][k-c[now]];
	for(ll i=1; i<=tot; i++) ans+=f[m][s[i]][K];
	printf("%lld", ans);
	return 0;
} 

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/108115644
car
ii