http://acm.hdu.edu.cn/showproblem.php?pid=4200
思路:经典的开关问题,高斯消元+枚举自由变量
代码:
/*
高斯消元+枚举自由变量
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int T , N ,M ;
int num[110] ;
int a[110][110] ;
int row , col ;
int ans[110] ;
int temp[110] ;
int res ;
void dfs(int u){
if(u == N){
for(int i=0;i<N;i++){
temp[i] = ans[i] ;
}
int sum = 0;
for(int i=row-1;i>=0;i--){
int rr = a[i][N] ;
for(int j=i+1;j<N;j++){
rr = (rr ^ (a[i][j] && temp[j])) ;
}
temp[i] = rr ;
}
for(int i=0;i<N;i++)
sum += temp[i] ;
if(sum < res) res = sum ;
return ;
}
ans[u] = 0 ;
dfs(u+1) ;
ans[u] = 1 ;
dfs(u+1) ;
}
int gauss(){
int i, j;
row = col = 0 ;
for( ;row<N && col<N;row++,col++){
int max_r = row ;
for(i=row+1;i<N;i++){
if(a[max_r][col] < a[i][col]) max_r = i ;
}
if(max_r != row){
for(j=col ;j<=N;j++){
swap(a[row][j] ,a[max_r][j]);
}
}
if(a[row][col] == 0 ){
row-- ; continue ;
}
for(i=row+1;i<N;i++){
if(a[i][col] == 0) continue ;
for(j=col ;j<=N;j++){
a[i][j] = (a[i][j] ^ a[row][j]) ;
}
}
}
for(i=row;i<N;i++){
if(a[i][N] != 0) return -1 ;
}
res = 1000000 ;
memset(ans ,0 ,sizeof(ans)) ;
for(i=0;i<N;i++){ //将每一行的主元素化成非零
if(a[i][i]) continue ;
for(j=i+1;j<N;j++){
if(a[i][j]) break ;
}
if(j == N) break ;
for(int k=0;k<N;k++){
swap(a[k][i],a[k][j]) ;
}
}
dfs(row) ;
return res ;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&N, &M);
for(int i=0;i<N;i++){
scanf("%d",&num[i]);
}
memset(a, 0 ,sizeof(a));
for(int i=0;i<N;i++){
a[i][i] = 1 ;
for(int j=1;j<=M;j++){
if(i+j>=N) break ;
a[i][i+j] = 1 ;
}
for(int j=1;j<=M;j++){
if(i-j<0) break ;
a[i][i-j] = 1 ;
}
a[i][N] = num[i] ;
}
int ans = gauss() ;
if(ans == -1){
printf("impossible\n");
}
else{
printf("%d\n",ans);
}
}
return 0 ;
}