zoukankan      html  css  js  c++  java
  • [状压dp][dfs] Luogu P3160 局部极小值

    题目描述

    有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次。如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值。给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵。

    题解

    • 其实就是个简单的状压dp,有两种不同的情况,当前的数可以填入坑内或不填入坑内,分类就好了

    代码

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <iostream>
     4 #include <cstring>
     5 using namespace std;
     6 char a[10];
     7 int m,n,mo=12345678,vis[6][10],f[29][(1<<8)+10],g[1<<9],mn[6][10],num,x[30],y[30],dx[9]={-1,-1,-1,0,0,1,1,1},dy[9]={-1,0,1,-1,1,-1,0,1};
     8 int dp()
     9 {
    10     memset(f,0,sizeof(f)),f[0][0]=1;
    11     for (int i=0;i<(1<<num);i++) 
    12     {
    13         g[i]=n*m,memset(vis,0,sizeof(vis));
    14         for (int j=0;j<num;j++) if (!(i&(1<<j))) for (int k=0;k<9;k++) vis[x[j]+dx[k]][y[j]+dy[k]]=1;
    15         for (int j=1;j<=n;j++) for (int k=1;k<=m;k++) if (vis[j][k]) g[i]--;
    16     }
    17     for (int i=1;i<=n*m;i++)
    18     {
    19         for (int j=0;j<(1<<num);j++)
    20         {
    21             if (g[j]-i+1>0) (f[i][j]+=f[i-1][j]*(g[j]-i+1))%=mo;
    22             for (int k=0;k<num;k++) if((1<<k)&j) (f[i][j]+=f[i-1][j^(1<<k)])%=mo;
    23         }
    24     }
    25     return f[n*m][(1<<num)-1];    
    26 }
    27 int dfs(int X,int Y)
    28 {
    29     if (Y==m+1) X++,Y=1;
    30     if (X==n+1) return dp();
    31     int ans=dfs(X,Y+1);
    32     for (int i=0;i<9;i++) if (mn[X+dx[i]][Y+dy[i]]) return ans;
    33     x[num]=X,y[num++]=Y,mn[X][Y]=1,ans-=dfs(X,Y+1),ans=(ans+mo)%mo,mn[X][Y]=0,num--; return ans; 
    34 }
    35 int main()
    36 {
    37     scanf("%d%d",&n,&m);
    38     for (int i=1;i<=n;i++)
    39     {
    40         scanf("%s",a+1); 
    41         for (int j=1;j<=m;j++) if (a[j]=='X') mn[i][j]=1,x[num]=i,y[num++]=j; 
    42     }
    43     for (int i=0;i<num;i++) for (int j=0;j<i;j++) if (abs(x[i]-x[j])<2&&abs(y[i]-y[j])<2) return printf("0"),0;
    44     if (!num) printf("0"); else printf("%d",dfs(1,1));    
    45 }
  • 相关阅读:
    使用maven管理后,依然找不到需要的jar包
    ftp linux-500 OOPS问题解决-jooyong-ChinaUnix博客
    Linux命令 理解
    c++大数模板
    二分匹配专辑
    fzu2157(树形dp)
    fzu2158
    csu1356 :判断一个环是否为奇数环
    rmq模板
    zoj 3761(并查集+搜索)
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11224014.html
Copyright © 2011-2022 走看看