POJ 3185

View Code
  1 //Result:wizmann    3185    Accepted    728K    16MS    G++    2340B
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <iostream>
  8  
  9 using namespace std;
 10  
 11 #define print(x) cout<<x<<endl
 12 #define input(x) cin>>x
 13 #define SIZE 20
 14  
 15 /*
 16  * 先用高斯消元法求出正确解,然后通过穷举自由元dfs求出最优解
 17  */
 18  
 19 int mat[SIZE+5][SIZE+5];
 20 int ptr;
 21 int ans[SIZE],x[SIZE];
 22 int tmp_mat[SIZE+5][SIZE+5];
 23  
 24 void init()
 25 {
 26     for(int i=0;i<SIZE;i++)
 27     {
 28         if(i-1>=0) mat[i][i-1]=1;
 29         mat[i][i]=1;
 30         if(i+1<SIZE) mat[i][i+1]=1;
 31     }
 32 }
 33  
 34 int dfs(int v)
 35 {
 36     if(v==20)
 37     {
 38         int temp=0;  
 39         for(int i=0;i<SIZE;i++) x[i]=ans[i];  
 40         memcpy(tmp_mat,mat,sizeof(mat));
 41         for(int i=ptr-1;i>=0;i--)
 42         {  
 43             for(int j=i+1;j<SIZE;j++)
 44             {
 45                 tmp_mat[i][SIZE]^=(x[j]&tmp_mat[i][j]);
 46                 //设定自由元后,再次进行高斯消元,确定正确答案,从而求出最优解
 47             }
 48             x[i]=tmp_mat[i][SIZE];  
 49         }  
 50         for(int i=0;i<SIZE;i++)
 51         {
 52             if(x[i]) temp++;  
 53         }
 54         return temp;  
 55     }
 56     ans[v]=0;  
 57     int res=dfs(v+1);  
 58     ans[v]=1;  
 59     res=min(res,dfs(v+1));  
 60     return res;
 61 } 
 62  
 63  
 64 int gauss()
 65 {
 66     for(int row=0,col=0;row<SIZE&&col<SIZE;col++)
 67     {
 68         int zptr=-1;
 69         for(int i=row;i<SIZE;i++)
 70         {
 71             if(mat[i][col])
 72             {
 73                 zptr=i;
 74                 break;
 75             }
 76         }
 77         if(zptr==-1)
 78         {
 79             //print(col);
 80             continue;
 81         }
 82         for(int i=0;i<=SIZE;i++)
 83         {
 84             swap(mat[row][i],mat[zptr][i]);
 85         }
 86  
 87         for(int i=0;i<SIZE;i++) if(i!=row)
 88         {
 89             if(!mat[i][col]) continue;
 90             for(int j=0;j<=SIZE;j++)
 91             {
 92                 mat[i][j]^=mat[row][j];
 93             }
 94         }
 95         row++;
 96         ptr=row;
 97     }
 98     if(ptr==SIZE) 
 99     {
100         int ans=0;
101         for(int i=0;i<SIZE;i++)
102         {
103             if(mat[i][SIZE]) ans++;
104         }
105         return ans;
106     }
107     else return dfs(ptr);
108 }
109  
110  
111  
112 int main()
113 {
114     int a;
115     init();
116     for(int i=0;i<SIZE;i++)
117     {
118         input(a);
119         mat[i][SIZE]=a;
120     }
121     print(gauss());
122     return 0;
123 }

转载于:https://www.cnblogs.com/Wizmann/archive/2012/06/29/2570463.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值