状态表示:
f[i]=0
表示状态为i
不存在
f[i]=1
表示状态为i
存在
其中状态i 哪一个为1表示破产,0表示没破产
每次用老状态更新
状态计算
如果旧状态可以更新的新状态,并且新状态入不敷出,则把新状态置为1,即新状态存在
for(int k=0;k<n;k++)
if(!(i&(1<<k)))t+=w[j][k];
if(t>0)f[i|(1<<j)]=1;
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1030;
int f[N*N];
int w[N][N];
int n;
signed main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<N*N;i++)f[i]=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&w[i][j]);
f[0]=1;
for(int i=0;i<1<<n;i++)
{
//如果这个状态存在才能去更新其它状态
if(!f[i])continue;
for(int j=0;j<n;j++)
{
//如果状态已经存在,直接跳过
if((i&(1<<j))||f[i|1<<j])continue;
int t=0;
//计算会不会破产
for(int k=0;k<n;k++)
if(!(i&(1<<k)))t+=w[j][k];
if(t>0)f[i|(1<<j)]=1;
}
}
bool flag=false;
for(int i=0;i<n;i++)
{
if(f[((1<<n)-1)-(1<<i)])
{
flag=true;
printf("%d ",i+1);
}
}
if(!flag)printf("0");
printf("\n");
}
}