1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std;
typedef long long LL;
const int maxn=25, maxN=2e4+5;
int n,m,N,mp[maxn][maxn],er[maxn],b0;
int w[maxN]; int get(int x) { int re=0; for(; x; x-=(x&(-x))) re++; return re; }
int Sb[maxn],bl[maxn],br[maxn]; LL f[205][2],num[205]; int main() { fo(i,1,20) er[i]=1<<(i-1);
scanf("%d %d",&n,&m); fo(i,1,n) fo(j,1,m) scanf("%d",&mp[i][j]); if (n>m) { fo(i,1,n) fo(j,(i<=m)?i:1,m) swap(mp[i][j],mp[j][i]); swap(n,m); } N=(1<<n)-1;
fo(j,1,m) { Sb[j]=Sb[j-1]; fo(i,1,n) if (mp[i][j]) { bl[j]+=er[i]; br[i]++; Sb[j]++; b0++; } } fo(s,0,N) w[s]=get(s);
fo(s,0,N) { int st=0; fo(i,1,n) if (s&er[i]) { if (!br[i]) {st=-1; break;} st+=br[i]; } if (st==-1) continue; memset(f,0,sizeof(f)); f[st][0]=1; fo(j,1,m) if (Sb[j]-Sb[j-1]) fd(i,min(st+Sb[j],b0),st) { LL g[2]={f[i][0],f[i][1]}; f[i][0]=f[i][1]=0; fo(k,0,1) { f[i][k]+=g[k]; if (i+get(bl[j]-(s&bl[j]))<=b0) f[i+w[bl[j]-(s&bl[j])]][k^1]+=g[k]; } } fo(i,st,b0) { fo(k,0,1) if ((get(s)^k)&1) num[i]+=f[i][k]; else num[i]-=f[i][k]; } }
long double ans=0; fo(x,1,b0) ans+=num[x]*(long double)b0/x;
printf("%.5f\n",(double)ans); }
|