Ural 1519 Formula 1 基于连通性的状态压缩动态规划

来源:互联网 发布:显示器品牌知乎 编辑:程序博客网 时间:2024/05/22 10:56

2kb代码

#include <bits/stdc++.h>#define mask 600000#define N 15#define Hash 1999987#define mc(p) memset(p,0,sizeof(p))using namespace std;typedef long long LL;int a[N][N],e[Hash+1],hash[Hash+1];int n,m,ex,ey,k,tot[2];LL sum[2][mask],ans;int F[2][mask];void init() {    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++) {        char s[N];        scanf("%s",s+1);        for (int j=1;j<=m;j++) {            a[i][j]=s[j]=='.';            a[i][j]?ex=i,ey=j:0;        }    }}void pre() { for (int i=1;i<=m;i++) e[i]=i<<1; }int ha(int s,LL d) {    int cur=s%Hash;    while (hash[cur]) {        if (F[k][hash[cur]]==s)            return sum[k][hash[cur]]+=d;        cur=(cur+1)%Hash;    }    hash[cur]=++tot[k];    F[k][tot[k]]=s,sum[k][tot[k]]=d;}void solve() {    tot[0] = 1 , sum[0][1] = 1;    for (int i=1;i<=n;i++) {        for (int j=1;j<=m;j++) {            k^=1; mc(hash),mc(sum[k]),mc(F[k]);            tot[k]=0;            for (int u=1;u<=tot[k^1];u++) {                int s = F[k^1][u];                LL d = sum[k^1][u];                int p = (s >> e[j-1]) % 4;                int q = (s >> e[j]) % 4;                int t = 0;                if (!a[i][j])                    !p&&!q?ha(s,d):0;                else {                    if (!p&&!q)                         a[i+1][j]&&a[i][j+1]?ha(s+1*(1<<e[j-1])+2*(1<<e[j]),d):0;                    if (!p&&q)                         a[i][j+1]?ha(s,d):0,                        a[i+1][j]?ha(s-q*(1<<e[j])+q*(1<<e[j-1]),d):0;                    if (p&&!q)                         a[i+1][j]?ha(s,d):0,                        a[i][j+1]?ha(s-p*(1<<e[j-1])+p*(1<<e[j]),d):0;                    if (p==1&&q==1) {                        int cp=1;                        for (int v=j+1;v<=n;v++) {                            int w=(s>>e[v])% 4;                            w==1?cp++:0;                            w==2?cp--:0;                            if (!cp) { t=s-(1<<e[v]); break; }                        }                        ha(t-(1<<e[j-1])-(1<<e[j]),d);                    }                    if (p==2&&q==2) {                        int cp=1;                        for (int v=j-2;v>=1;v--) {                            int w=(s>>e[v])%4;                            w==2?cp++:0;                            w==1?cp--:0;                            if (!cp) { t=s+(1<<e[v]); break; }                        }                        ha(t-2*(1<<e[j-1])-2*(1<<e[j]),d);                    }                    if (p==2&&q==1)                         ha(s-2*(1<<e[j-1])-1*(1<<e[j]),d);                    if (p==1&&q==2)                         i==ex&&j==ey?ans+=d:0;                }            }        }        for (int i=1;i<=tot[k];i++) F[k][i]<<=2;    }}int main() {    init();    pre();    if (ex == 0) return puts("0"),0;    solve();    cout<<ans<<endl;    return 0;}
0 0
原创粉丝点击