您的位置:首页 > 其它

Hdu 1693 插头dp

2013-08-14 17:52 288 查看
这题在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

;
int jz
;
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
;
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

;
int jz
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: