HDU 4499 Cannon (状态)

棋盘:N*M

已放好Q个chess

现在放conno  使得:任意2个conno不相斥  

          2个conno相斥满足:1 、在水平、垂直直线上

                                                2、中间只有1个棋子(chess 或者 conno)

这个题  (01110)这种不能直接排除掉,因为111-》炮炮炮      chess泡泡这个是可以的. 

#define chess 1
#define conno 2

int N , M , Q  , ans ;
int cannot[6] ;
int table[6][6]  , oldtable[6][6] ;
int row_state[6] ;

int cango(int row){
    int i , j , k , sum ;
    for(i = 0 ; i < M ; i++)
      for(j = i+2 ; j < M ; j++){
         if(table[row][i] == conno && table[row][j] == conno){
              sum = 0 ;
              for(k = i+1 ; k < j ; k++){
                  if(table[row][k])
                      sum++ ;
              }
              if(sum == 1)
                return 0 ;
         }
    }
    if(row < 2)
        return 1 ;
    int s , t ;
    for(j = 0 ; j < M ; j++)
        for(s = 0 ; s <= row ; s++)
            for(t = s+2 ; t <= row ; t++)
                  if(table[s][j] == conno && table[t][j] == conno){
                      sum = 0 ;
                      for(k = s+1 ; k < t ; k++){
                          if(table[k][j])
                              sum++ ;
                      }
                      if(sum == 1)
                        return 0 ;
                   }
    return 1 ;
}

int Count(){
    int i , j , sum = 0 ;
    for(i = 0 ; i < N ; i++){
        for(j = 0 ; j < M ; j++){
            if((1<<j) & row_state[i])
                sum++ ;
        }
    }
    return sum ;
}

void dfs(int row){
     if(row == N){
         ans = max(ans , Count()) ;
         return ;
     }
     for(int i = 0 ; i < (1<<M) ; i++){
        if(i & cannot[row])
            continue ;
        row_state[row] =  i ;
        for(int j = 0 ; j < M ; j++){
            table[row][j] = oldtable[row][j] ;
            if(table[row][j] == chess)
                continue ;
            if((1<<j) & i)
                table[row][j] = conno ;
            else
                table[row][j] = 0 ;
        }
        if(! cango(row))
            continue ;
        dfs(row+1) ;
     }
}

int DP(){
    ans = 0 ;
    dfs(0) ;
    return ans ;
}

int main(){
    int i , j , x , y ;
    while(scanf("%d%d%d",&N,&M,&Q) != EOF){
        memset(cannot , 0 , sizeof(cannot)) ;
        memset(table , 0 , sizeof(table)) ;
        memset(oldtable , 0 , sizeof(oldtable)) ;
        for(i = 1 ; i <= Q ; i++){
            scanf("%d%d",&x ,&y) ;
            cannot[x] |= (1<<y) ;
            table[x][y] =  oldtable[x][y] = chess ;
        }
        cout<<DP()<<endl ;
    }
    return 0 ;
}

 

你可能感兴趣的:(HDU 4499 Cannon (状态))