本文主要是介绍HDU 1693 Eat the Trees(插头dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693
插头dp板题。。。学了学cdq大神的论文和kuangbin大神的写法
附一个题解http://www.docin.com/p-741918386.html
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int HASH=10007;
const int STATE=1e6+10;
const int MAXD=15;
int n,m;
int code[MAXD],maze[MAXD][MAXD];
struct HASHMAP
{int head[HASH],next[STATE],state[STATE],size;long long f[STATE];void init(){size=0;memset(head,-1,sizeof(head));}void push(int st,long long ans){int i,h=st%HASH;for(i=head[h];i!=-1;i=next[i])if(st==state[i]){f[i]+=ans;return;}f[size]=ans;state[size]=st;next[size]=head[h];head[h]=size++;}
}hm[2];
void shift(int *code,int m)
{for(int i=m;i>0;i--){code[i]=code[i-1];}code[0]=0;
}
void decode(int *code,int m,int st)
{for(int i=m;i>=0;i--){code[i]=st&1;st>>=1;}
}
int encode(int *code,int m)
{int i,st=0;for(int i=0;i<=m;i++){st<<=1;st|=code[i];}return st;
}
void init()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&maze[i][j]);for(int i=1;i<=n;i++)maze[i][m+1]=maze[i][0]=0;for(int i=1;i<=m;i++)maze[0][i]=maze[n+1][i]=0;
}
void dpblank(int i,int j,int cur)
{int left,up;for(int k=0;k<hm[cur].size;k++){decode(code,m,hm[cur].state[k]);left=code[j-1];up=code[j];if(left&&up){code[j-1]=code[j]=0;if(j==m)shift(code,m);hm[cur^1].push(encode(code,m),hm[cur].f[k]);}else if(left||up){if(maze[i][j+1]){code[j-1]=0;code[j]=1;hm[cur^1].push(encode(code,m),hm[cur].f[k]);}if(maze[i+1][j]){code[j-1]=1;code[j]=0;if(j==m)shift(code,m);hm[cur^1].push(encode(code,m),hm[cur].f[k]);}}else{if(maze[i][j+1]&&maze[i+1][j]){code[j]=code[j-1]=1;hm[cur^1].push(encode(code,m),hm[cur].f[k]);}}}
}
void dpblock(int i,int j,int cur)
{for(int k=0;k<hm[cur].size;k++){decode(code,m,hm[cur].state[k]);code[j-1]=code[j]=0;if(j==m)shift(code,m);hm[cur^1].push(encode(code,m),hm[cur].f[k]);}
}
void solve()
{int cur=0;ll ans=0;init();hm[cur].init();hm[cur].push(0,1);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){hm[cur^1].init();if(maze[i][j])dpblank(i,j,cur);elsedpblock(i,j,cur);cur^=1;}}for(int i=0;i<hm[cur].size;i++)ans+=hm[cur].f[i];printf("There are %lld ways to eat the trees.\n",ans);
}
int main()
{//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int T;scanf("%d",&T);for(int _=1;_<=T;_++){printf("Case %d: ",_);solve();}return 0;
}
这篇关于HDU 1693 Eat the Trees(插头dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!