Hdu 1693 插头dp
2013-08-14 17:52
288 查看
这题在ural 1519的基础上做了修改。
【多条回路】
不分左括号右括号,只有有括号无括号(可以不用4进制用2进制,实践证明2进制略快)
两个插头能合并时一定要合并
【多条回路】
不分左括号右括号,只有有括号无括号(可以不用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; }
相关文章推荐
- HDU 1693 二进制表示的简单插头dp
- HDU 1693(状态压缩 插头DP)
- HDU 1693(Eat the Trees-不用匹配的插头Dp)
- HDU 1693 Eat the Trees(插头DP)
- hdu 1693 Eat the Trees (基础插头dp)
- HDU-1693-插头dp
- hdu 1693 Eat the Trees 插头dp入门题
- hdu 1693 Eat the Trees 插头dp
- HDU 1693 新的恐惧,插头Dp
- HDU 1693 Eat the Trees (插头DP,闭合路径)
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
- hdu 1693(插头DP简单题,多条回路)
- HDU - 1693 Eat the Trees(多回路插头DP)
- hdu 1693 : Eat the Trees 【插头dp 入门】
- hdu 1693 插头DP
- hdu 1693 插头dp
- HDU 1693 插头dp入门详解
- HDU 1693 Eat the Trees 插头DP
- HDU 1693 Eat the Trees(插头DP,多条回路)
- hdu 1693 Eat the Trees 插头dp