hdu5113Black And White dfs暴搜 +剪枝

//n(n<=5)*m(m<=5)的格子
//k种颜料,每种颜料有ai个
//问这k种颜料能否将这n*m涂满且
//每相邻的格子颜色不同
//暴搜 , 剪枝剩下的颜色的数量大于剩下(sum+1)/2
//直接return
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 30 ;
int map[maxn][maxn] ;
int a[maxn] ;
int n , m , k ;
bool dfs(int x , int y , int sum)
{
    y++ ;
    if(y == m){
       x++ ;
       y = 0 ;
    }
    if(x ==n){
       return true ;
    }
    for(int i = 1;i <= k;i++)
    if(a[i] > (sum+1)/2)return false ; 
    for(int i = 1;i <= k;i++)
    if(a[i]){
       int px = x - 1 ;
       int py = y - 1 ;
       if(px >= 0 && map[px][y] == i)
       continue ;
       if(py >=0 && map[x][py] == i)
       continue ;
       map[x][y] = i ;
       a[i]-- ;
       if(dfs(x , y , sum-1))return true ;
       a[i]++ ;
    }
    return false  ;
}
int main()
{
    int t ;
    int cas = 0 ;
    scanf("%d" , &t) ;
    while(t--)
    {
        scanf("%d%d%d" , &n , &m , &k) ;
        for(int i = 1;i <= k;i++)
        scanf("%d"  , &a[i]) ;
        printf("Case #%d:\n" , ++cas);
        if(dfs(0 , -1 , n*m))
        {
            puts("YES") ;
            for(int i = 0;i < n;i++)
               for(int j = 0;j < m;j++)
                 printf("%d%c" , map[i][j] , j == m - 1?'\n':' ') ;
        }
        else puts("NO") ;
    }
    return 0 ;
}

你可能感兴趣的:(hdu5113Black And White dfs暴搜 +剪枝)