CERC 2012 A

题意:有一堆人之间有借钱关系,给你一个关系矩阵Aij表示i欠j多少钱。若是有一个人他的总资产是负的,他可以从矩阵中去除和他一行一列的数据都会去除。问可以被最后留下来的那个人可能是那些?

思路:状态压缩dp表示当前状态可不可以达到,每次状态转移都两重循环判断第j个人能不能被去除。若可以标记,一直递推下去就行了。

代码如下:

 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-07-04 08:12
 5  * Filename     : cerc_A.cpp
 6  * Description     : 
 7  * ************************************************/
 8 
 9 #include <iostream>
10 #include <cstdio>
11 #include <cstring>
12 #include <cstdlib>
13 #include <cmath>
14 #include <algorithm>
15 #include <queue>
16 #include <stack>
17 #include <vector>
18 #include <set>
19 #include <map>
20 #define MP(a, b) make_pair(a, b)
21 #define PB(a) push_back(a)
22 
23 using namespace std;
24 typedef long long ll;
25 typedef pair<int, int> pii;
26 typedef pair<unsigned int,unsigned int> puu;
27 typedef pair<int, double> pid;
28 typedef pair<ll, int> pli;
29 typedef pair<int, ll> pil;
30 
31 const int INF = 0x3f3f3f3f;
32 const double eps = 1E-6;
33 const int LEN = 21;
34 int n, num[LEN][LEN];
35 bool dp[1<<20];
36 
37 int main()
38 {
39 //    freopen("in.txt", "r", stdin);
40 
41     int T;
42     cin >> T;
43     while(T--){
44         cin >> n;
45         memset(dp, false, sizeof dp);
46         for(int i=0; i<n; i++){
47             for(int j=0; j<n; j++){
48                 cin >> num[i][j];
49             }
50         }
51         dp[0] = true;
52         for(int i=0; i<(1<<n); i++){
53             if(dp[i]){
54                 for(int j=0; j<n; j++){
55                     if((i & (1<<j)) == 0) {
56                         int sum = 0;
57                         for(int k=0; k<n; k++) 
58                             if((~i)&(1<<k))sum += num[k][j];
59                         if(sum < 0){
60                             dp[i^(1<<j)] = true;
61                         }    
62                     }
63                 }
64             }
65         }
66         vector<int> ans;
67         ans.clear();
68         for(int i=0; i<n; i++){
69             if(dp[(1<<n)-1-(1<<i)]) ans.PB(i+1);
70         }
71         if(ans.size() == 0){
72             cout << 0 << endl;
73             continue;
74         }    
75         for(int i=0; i<ans.size(); i++){
76             cout << ans[i];
77                if(i != ans.size()-1) cout << " ";    
78         }
79         cout << endl;
80     }
81     return 0;
82 }
View Code

 

posted @ 2014-07-04 09:05  张小豪  阅读(489)  评论(0编辑  收藏  举报