对Dp还不是很熟悉,偶然看到Discuss上有人说Dp可解,我便试着实现了一下。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = (-1u>>1);
int n, m;
#define N 16
#define M 300
int a[N][M];
int fbd[N];
bool done[1 << N];
int dp[1 << N];
int sum[N];
void init(){
for (int i = 0; i < n; i++){
fbd[i] = 0;
for (int j = 0; j < n; j++){
for (int k = 0; k < m; k++){
if (a[i][k] & a[j][k]){
fbd[i] |= (1 << j);
break;
}
}
}
}
for (int i = 0; i < (1 << n); i++)done[i] = 0, dp[i] = 0;
for (int i = 0; i < n; i++){
sum[i] = 0;
for (int j = 0; j < m; j++){
sum[i] += a[i][j];
}
}
}
void doit(int u){
if (done[u])
return ;
done[u] = 1;
for (int i = 0; i < n; i++){
if ((1 << i) & u){
doit((u | (fbd[i])) - fbd[i]);
dp[u] = max(dp[u], sum[i] + dp[(u | (fbd[i])) - fbd[i]]);
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while (scanf("%d %d", &n, &m) != EOF){
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
scanf("%d", &a[i][j]);
}
}
init();
doit((1 << n) - 1);
if (dp[(1 << n) - 1] == m)puts("Yes, I found it");
else puts("It is impossible");
}
return 0;
}