Hdu 1693 插头dp

来源:互联网 发布:淘宝销售排行榜 编辑:程序博客网 时间:2024/04/28 07:18
这题在ural 1519的基础上做了修改。
【多条回路】
不分左括号右括号,只有有括号无括号(可以不用4进制用2进制,实践证明2进制略快)
两个插头能合并时一定要合并

//hdu_1693_括号表示2进制#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>typedef long long LL;using namespace std;const int N=15;const int HASH=15111;const int STATE=20000;const int INF=0x3f3f3f3f;LL ans;int n,m;int map[N][N];int jz[N];int ex,ey;struct HASHMAP{    int head[HASH],next[STATE],size;    int state[STATE];    LL f[STATE];    void init()    {        size=0;        memset(head,-1,sizeof(head));    }    void push(int st,LL ans)    {        int i;        int h=st%HASH;        for(i=head[h];i!=-1;i=next[i])          if(state[i]==st)          {              f[i]+=ans;              return;          }        state[size]=st;        f[size]=ans;        next[size]=head[h];        head[h]=size++;    }}hm[2];void shift(int cur){    for(int i=0;i<hm[cur].size;i++)         hm[cur].state[i]<<=1;}inline int cp(int p,int i){    return p&(~(1<<jz[i]));}inline int cp(int p,int i,int j){    return p&(~(1<<jz[i]))&(~(1<<jz[j]));}inline int cp(int p,int i,int j,int k){    return p&(~(1<<jz[i]))&(~(1<<jz[j]))&(~(1<<jz[k]));}inline int getp(int p,int i){    return 1&(p>>jz[i]);}inline int pp(int i,int k){   return k<<jz[i];}void dp(int i,int j,int cur){    for(int k=0;k<hm[cur].size;k++)        {int s=hm[cur].state[k];         LL data=hm[cur].f[k];         int left=getp(s,j);         int up=getp(s,j+1);         if (left==0&&up==0)            {if (map[i][j+1]&&map[i+1][j])                {                    hm[cur^1].push(s|pp(j,1)|pp(j+1,1),data);                }             continue;            }         if (left==0||up==0)            {   int w=left+up;                int tmp=cp(s,j,j+1);                if (map[i][j+1])               hm[cur^1].push(tmp|pp(j+1,w),data);                if (map[i+1][j])               hm[cur^1].push(tmp|pp(j,w),data);                continue;            }         if (left==1&&up==1)            {   hm[cur^1].push(cp(s,j,j+1),data);                if (i==ex&&j==ey) ans+=data;                continue;            }        }}char str[N];void init(){   scanf("%d%d",&n,&m);    memset(map,0,sizeof(map));    ex=-1;    for(int i=0;i<n;i++)        for(int j=0;j<m;j++)            {scanf("%d",&map[i][j]);             if(map[i][j])                {ex=i;ey=j;}            }}void solve(){    int cur=0;    ans=0;    hm[cur].init();    hm[cur].push(0,1);    for(int i=0;i<n;i++)        {for(int j=0;j<m;j++)            if (map[i][j])            {hm[cur^1].init();             dp(i,j,cur);             cur^=1;            }         shift(cur);        }    printf("%I64d ways to eat the trees.\n",ans);}void prepared_jinzhi(){    jz[0]=0;    for (int i=1;i<=m;i++)        jz[i]=i;}int main(){   int cas,i=0;    scanf("%d",&cas);    while(cas--)    {   i++;printf("Case %d: There are ",i);        init();        prepared_jinzhi();        if(ex==-1)        {            printf("%d ways to eat the trees.\n",1);            continue;        }        solve();    }    return 0;}

//hdu_1693_括号表示4进制#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>typedef long long LL;using namespace std;const int N=15;const int HASH=15111;const int STATE=20000;const int INF=0x3f3f3f3f;LL ans;int n,m;int map[N][N];int jz[N];int ex,ey;struct HASHMAP{    int head[HASH],next[STATE],size;    int state[STATE];    LL f[STATE];    void init()    {        size=0;        memset(head,-1,sizeof(head));    }    void push(int st,LL ans)    {        int i;        int h=st%HASH;        for(i=head[h];i!=-1;i=next[i])          if(state[i]==st)          {              f[i]+=ans;              return;          }        state[size]=st;        f[size]=ans;        next[size]=head[h];        head[h]=size++;    }}hm[2];void shift(int cur){    for(int i=0;i<hm[cur].size;i++)         hm[cur].state[i]<<=2;}inline int cp(int p,int i){    return p&(~(3<<jz[i]));}inline int cp(int p,int i,int j){    return p&(~(3<<jz[i]))&(~(3<<jz[j]));}inline int cp(int p,int i,int j,int k){    return p&(~(3<<jz[i]))&(~(3<<jz[j]))&(~(3<<jz[k]));}inline int getp(int p,int i){    return 3&(p>>jz[i]);}inline int pp(int i,int k){   return k<<jz[i];}void dp(int i,int j,int cur){    for(int k=0;k<hm[cur].size;k++)        {int s=hm[cur].state[k];         LL data=hm[cur].f[k];         int left=getp(s,j);         int up=getp(s,j+1);         if (left==0&&up==0)            {if (map[i][j+1]&&map[i+1][j])                {                    hm[cur^1].push(s|pp(j,1)|pp(j+1,1),data);                }             continue;            }         if (left==0||up==0)            {   int w=left+up;                int tmp=cp(s,j,j+1);                if (map[i][j+1]) hm[cur^1].push(tmp|pp(j+1,w),data);                if (map[i+1][j]) hm[cur^1].push(tmp|pp(j,w),data);                continue;            }         if (left==1&&up==1)            {   hm[cur^1].push(cp(s,j,j+1),data);                if (i==ex&&j==ey) ans+=data;                continue;            }        }}void init(){   scanf("%d%d",&n,&m);    memset(map,0,sizeof(map));    ex=-1;    for(int i=0;i<n;i++)        for(int j=0;j<m;j++)            {scanf("%d",&map[i][j]);             if(map[i][j])                {ex=i;ey=j;}            }}void solve(){    int cur=0;    ans=0;    hm[cur].init();    hm[cur].push(0,1);    for(int i=0;i<n;i++)        {for(int j=0;j<m;j++)            if (map[i][j])            {             hm[cur^1].init();             dp(i,j,cur);             cur^=1;            }         shift(cur);        }    printf("%I64d ways to eat the trees.\n",ans);}void prepared_jinzhi(){    jz[0]=0;    for (int i=1;i<=m;i++)        jz[i]=i<<1;}int main(){   int cas,i=0;    scanf("%d",&cas);    while(cas--)    {   i++;printf("Case %d: There are ",i);        init();        prepared_jinzhi();        if(ex==-1)        {            printf("%d ways to eat the trees.\n",1);            continue;        }        solve();    }    return 0;}