剪枝是c[i] < ( n*m-cnt+1)/2 ,减掉很多没必要的搜索
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 7
using namespace std;
int a[MAX][MAX];
int c[MAX*MAX];
bool flag = false;
int t,n,m,k;
void dfs ( int cnt = 0 )
{
// cout << cnt << endl;
if ( cnt == n*m )
{
puts ("YES" );
for ( int i = 1 ; i <= n ; i++ )
{
for ( int j = 1 ; j < m ; j++ ) printf ( "%d " , a[i][j] );
printf ( "%d\n" , a[i][m] );
}
flag = true;
return;
}
for ( int i = 1 ; i <= k ; i++ )
if ( c[i] > (n*m-cnt+1)/2 ) return;
int x = cnt/m+1;
int y = cnt%m+1;
for ( int i = 1 ; i <= k ; i++ )
{
if ( flag ) return;
if ( !c[i] ) continue;
if(i==a[x-1][y]||i==a[x+1][y]||i==a[x][y+1]||i==a[x][y-1])
continue;
a[x][y] = i;
c[i]--;
dfs ( cnt + 1 );
a[x][y] = 0;
c[i]++;
}
}
int main ( )
{
scanf ( "%d" , &t );
int cc = 1;
while ( t-- )
{
scanf ( "%d%d%d" , &n , &m , &k );
for ( int i = 1 ; i <= k ; i++ ) scanf ( "%d" , &c[i] );
printf ( "Case #%d:\n" , cc++ );
memset ( a , 0 , sizeof ( a ) );
flag = false;
dfs ( );
if ( !flag ) puts ( "NO" );
}
}