hdu 搜索+剪枝

来源:互联网 发布:java调用三汇语音卡 编辑:程序博客网 时间:2024/05/14 17:14

剪枝是c[i] < ( n*m-cnt+1)/2 ,减掉很多没必要的搜索

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define MAX 7using 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" );    }}


0 0
原创粉丝点击