zoj 3213 Beautiful Meadow
来源:互联网 发布:街机模拟器mac版 编辑:程序博客网 时间:2024/05/22 19:22
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3213
题目大意:求最大简单路径。
题目思路:插头dp,增加独立插头,有可不走点需要特殊处理一下。这个题写得相当纠结啊,写括号表示法的时候有一个地方忘了处理了,花了一晚上都没调出来,今早上用最小表示法打数据对比才找到了错误,真是相当辛苦啊,不过括号表示法的效率依然不错,跑了80ms。
最小表示法:
#include<stdio.h>#include<string.h>#define Max 20000#define Hash 3007#define __int64 long longint code[15],ch[15],mp[15][15],ex,ey,n,m,cur,ans,num;char str[15];inline int max(int a,int b){ return a>b?a:b;}struct node{ int size,next[Max],p[Hash],f[Max]; __int64 state[Max]; inline void init() { memset(p,-1,sizeof(p)); size=0; } inline void push(__int64 st,int val) { int i,u=st%Hash; for(i=p[u];i!=-1;i=next[i]) { if(state[i]==st) { if(val>f[i]) f[i]=val; return; } } state[size]=st;f[size]=val; next[size]=p[u]; p[u]=size++; }}dp[2];inline void decode(__int64 st){ memset(ch,0,sizeof(ch)); num=st&7; st>>=3; for(int i=m;i>=0;i--) { code[i]=st&7; st>>=3; }}inline __int64 encode(){ __int64 st=0; int cnt=1; memset(ch,-1,sizeof(ch)); ch[0]=0; for(int i=0;i<=m;i++) { if(ch[code[i]]==-1) ch[code[i]]=cnt++; st<<=3; st|=ch[code[i]]; } st<<=3; st|=num; return st;}inline void shift(){ for(int k=0;k<dp[cur].size;k++) { num=dp[cur].state[k]&7; dp[cur^1].push((dp[cur].state[k]>>3)|num,dp[cur].f[k]); }}inline void dpblank(int i,int j){ int k,l,left,up; for(k=0;k<dp[cur].size;k++) { int tmp=dp[cur].f[k]+mp[i][j]; decode(dp[cur].state[k]); left=code[j-1],up=code[j]; if(left&&up) { if(left!=up) { code[j-1]=code[j]=0; for(l=0;l<=m;l++) if(code[l]==up) code[l]=left; dp[cur^1].push(encode(),tmp); } } else if(left||up) { if(mp[i][j+1]) { code[j-1]=0;code[j]=left+up; dp[cur^1].push(encode(),tmp); } if(mp[i+1][j]) { code[j-1]=left+up,code[j]=0; dp[cur^1].push(encode(),tmp); } if(num<2) { num++; code[j-1]=code[j]=0; dp[cur^1].push(encode(),tmp); } } else { code[j-1]=code[j]=0; dp[cur^1].push(encode(),dp[cur].f[k]); if(mp[i][j+1]&&mp[i+1][j]) { code[j-1]=code[j]=7; dp[cur^1].push(encode(),tmp); } if(num<2) { num++; if(mp[i][j+1]) { code[j-1]=0,code[j]=7; dp[cur^1].push(encode(),tmp); } if(mp[i+1][j]) { code[j-1]=7,code[j]=0; dp[cur^1].push(encode(),tmp); } } } }}void solve(){ int i,j,k; cur=0; dp[0].init(); dp[0].push(0,0); for(i=1;i<=n;i++) { dp[cur^1].init(); shift(); cur^=1; for(j=1;j<=m;j++) { if(mp[i][j]) { dp[cur^1].init(); dpblank(i,j); cur^=1; } } } for(k=0;k<dp[cur].size;k++) if(ans<dp[cur].f[k]) ans=dp[cur].f[k]; printf("%d\n",ans);}int main(){ int i,j,t; // freopen("D:/out.txt","w",stdout); scanf("%d",&t); while(t--) { ans=0; scanf("%d%d",&n,&m); ex=0; memset(mp,0,sizeof(mp)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&mp[i][j]); ans=max(ans,mp[i][j]); } solve(); } return 0;}
括号表示法:
#include<stdio.h>#include<string.h>#include<stdlib.h>#define Max 20010#define Hash 3007int n,m,ex,ey,cur,mp[15][15],a1,a2,a3,b1,b2,b3,ans,num;int stack[15],f[15];char str[15];struct node{ int size,next[Max],p[Hash],state[Max]; int f[Max]; inline void init() { memset(p,-1,sizeof(p)); size=0; } inline void push(int st,int val) { int i,u=st%Hash; for(i=p[u];i!=-1;i=next[i]) { if(state[i]==st) { if(f[i]<val) f[i]=val; return; } } state[size]=st;f[size]=val; next[size]=p[u]; p[u]=size++; }}dp[2];inline void decode(int st){ int top=0; st>>=2; for(int i=0;i<=m;i++) { if((st&3)==1) stack[top++]=i; else if((st&3)==2) { f[stack[top-1]]=i+1; f[i]=stack[top-1]+1; top--; } st>>=2; }}inline void shift(){ for(int k=0;k<dp[cur].size;k++) { num=dp[cur].state[k]&3; dp[cur].state[k]^=num; dp[cur^1].push((dp[cur].state[k]<<2)|num,dp[cur].f[k]); }}inline void dpblank(int i,int j){ int k,left,up; for(k=0;k<dp[cur].size;k++) { int st=dp[cur].state[k]; int tmp=dp[cur].f[k]+mp[i][j]; left=st&a3;up=st&b3;num=st&3; if(left&&up) { decode(st); if(left==a2&&up==b1) dp[cur^1].push(st^left^up,tmp); else if(left==a1&&up==b1) dp[cur^1].push(st^left^up^(3<<(2*f[j])),tmp); else if(left==a2&&up==b2) dp[cur^1].push(st^left^up^(3<<(2*f[j-1])),tmp); else if(left==a3&&up==b3) dp[cur^1].push(st^left^up,tmp); else if(left==a3) dp[cur^1].push((st^left^up)|(3<<(2*f[j])),tmp); else if(up==b3) dp[cur^1].push((st^left^up)|(3<<(2*f[j-1])),tmp); } else if(left) { if(mp[i][j+1]) dp[cur^1].push((st^left)|(left<<2),tmp); if(mp[i+1][j]) dp[cur^1].push(st,tmp); if(num<2) { num++;decode(st);int ss=(st^left^up)|num;if(left!=a3)ss|=3<<(2*f[j-1]); dp[cur^1].push(ss,tmp); } } else if(up) { if(mp[i][j+1]) dp[cur^1].push(st,tmp); if(mp[i+1][j]) dp[cur^1].push((st^up)|(up>>2),tmp); if(num<2) { num++;decode(st);int ss=(st^left^up)|num;if(up!=b3)ss|=3<<(2*f[j]); dp[cur^1].push(ss,tmp); } } else { dp[cur^1].push(st^left^up,dp[cur].f[k]); if(mp[i][j+1]&&mp[i+1][j]) dp[cur^1].push(st|a1|b2,tmp); if(num<2) { num++; if(mp[i][j+1]) dp[cur^1].push((st|b3)|num,tmp); if(mp[i+1][j]) dp[cur^1].push((st|a3)|num,tmp); } } }}inline void solve(){ int i,j,k; cur=0; dp[0].init(); dp[0].push(0,0); for(i=1;i<=n;i++) { dp[cur^1].init(); shift(); cur^=1; b1=4;b2=8; for(j=1;j<=m;j++) { a1=b1;a2=b2;a3=a1|a2; b1<<=2;b2<<=2;b3=b1|b2; if(mp[i][j]) { dp[cur^1].init(); dpblank(i,j); cur^=1; } } } for(k=0;k<dp[cur].size;k++) if(ans<dp[cur].f[k]) ans=dp[cur].f[k]; printf("%d\n",ans);}int main(){ int i,j,t; //freopen("D:/out2.txt","w",stdout); scanf("%d",&t); while(t--) { ans=0; scanf("%d%d",&n,&m); memset(mp,0,sizeof(mp)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&mp[i][j]); if(ans<mp[i][j]) ans=mp[i][j]; } solve(); } return 0;}
括号表示法的另一种写法(不加独立插头个数限制):
#include<stdio.h>#include<string.h>#include<stdlib.h>#define Max 20010#define Hash 3007int n,m,ex,ey,cur,mp[15][15],a1,a2,a3,b1,b2,b3,ans;int stack[15],f[15];char str[15];struct node{ int size,next[Max],p[Hash],state[Max]; int f[Max]; inline void init() { memset(p,-1,sizeof(p)); size=0; } inline void push(int st,int val) { int i,u=st%Hash; for(i=p[u];i!=-1;i=next[i]) { if(state[i]==st) { if(f[i]<val) f[i]=val; return; } } state[size]=st;f[size]=val; next[size]=p[u]; p[u]=size++; }}dp[2];inline void decode(int st){ int top=0; for(int i=0;i<=m;i++) { if((st&3)==1) stack[top++]=i; else if((st&3)==2) { f[stack[top-1]]=i; f[i]=stack[top-1]; top--; } st>>=2; }}inline void shift(){ for(int k=0;k<dp[cur].size;k++) dp[cur^1].push((dp[cur].state[k]<<2),dp[cur].f[k]);}inline void dpblank(int i,int j){ int k,left,up; for(k=0;k<dp[cur].size;k++) { int st=dp[cur].state[k]; int tmp=dp[cur].f[k]+mp[i][j]; left=st&a3;up=st&b3; if(left&&up) { decode(st); if(left==a2&&up==b1) dp[cur^1].push(st^left^up,tmp); else if(left==a1&&up==b1) dp[cur^1].push(st^left^up^(3<<(2*f[j])),tmp); else if(left==a2&&up==b2) dp[cur^1].push(st^left^up^(3<<(2*f[j-1])),tmp); else if(left==a3&&up==b3) { if((st^left^up)==0&&ans<tmp) ans=tmp; } else if(left==a3) dp[cur^1].push((st^left^up)|(3<<(2*f[j])),tmp); else if(up==b3) dp[cur^1].push((st^left^up)|(3<<(2*f[j-1])),tmp); } else if(left) { if(mp[i][j+1]) dp[cur^1].push((st^left)|(left<<2),tmp); if(mp[i+1][j]) dp[cur^1].push(st,tmp); if(left!=a3) { decode(st); dp[cur^1].push((st^left^up)|(3<<(2*f[j-1])),tmp); } if(left==a3) { if((st^left^up)==0&&ans<tmp) ans=tmp; } } else if(up) { if(mp[i][j+1]) dp[cur^1].push(st,tmp); if(mp[i+1][j]) dp[cur^1].push((st^up)|(up>>2),tmp); if(up!=b3) { decode(st); dp[cur^1].push((st^left^up)|(3<<(2*f[j])),tmp); } if(up==b3) { if((st^left^up)==0&&ans<tmp) ans=tmp; } } else { dp[cur^1].push(st^left^up,dp[cur].f[k]); if(mp[i][j+1]&&mp[i+1][j]) dp[cur^1].push(st|a1|b2,tmp); if(mp[i][j+1]) dp[cur^1].push((st|b3),tmp); if(mp[i+1][j]) dp[cur^1].push((st|a3),tmp); } }}inline void solve(){ int i,j; cur=0; dp[0].init(); dp[0].push(0,0); for(i=1;i<=n;i++) { dp[cur^1].init(); shift(); cur^=1; b1=1;b2=2; for(j=1;j<=m;j++) { a1=b1;a2=b2;a3=a1|a2; b1<<=2;b2<<=2;b3=b1|b2; if(mp[i][j]) { dp[cur^1].init(); dpblank(i,j); cur^=1; } } } printf("%d\n",ans);}int main(){ int i,j,t; //freopen("D:/out2.txt","w",stdout); scanf("%d",&t); while(t--) { ans=0; scanf("%d%d",&n,&m); memset(mp,0,sizeof(mp)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&mp[i][j]); if(ans<mp[i][j]) ans=mp[i][j]; } solve(); } return 0;}
- zoj 3213 Beautiful Meadow
- ZOJ 3213 Beautiful Meadow
- zoj 3213 Beautiful Meadow 插头dp
- zoj 3213 Beautiful Meadow(插头dp)
- ZOJ 3213 Beautiful Meadow(插头DP)
- zoj 2850 Beautiful Meadow
- ZOJ 2850 Beautiful Meadow
- ZOJ 2850 Beautiful Meadow
- ZOJ 2850 Beautiful Meadow
- ZOJ 1850 Beautiful Meadow
- zoj 2850 Beautiful Meadow
- ZOJ 2850 Beautiful Meadow
- ZOJ 2850Beautiful Meadow
- ZOJ 2850 Beautiful Meadow
- zoj 2850 Beautiful Meadow 水题
- ZOJ 3213 Beautiful Meadow 解题报告(插头DP)
- zoj 2850 Beautiful Meadow(水~)
- [水] zoj 2850 Beautiful Meadow
- 长度为0的数组只用在结构体的最后一个成员,用以做一个地址标记,以后用。
- 看《高性能MySQL》(第二版)中文版后的笔记
- 小摩称苹果电视今年没戏但iPay有望
- servlet监听器
- Merkle Tree 或 Hash Tree
- zoj 3213 Beautiful Meadow
- Unity网络相关流程
- DirectX9 SDK Samples(2) Tutorial2-Rendering Vertices
- 比较dbms_job几个模拟多线程方法在调用延迟上的差异
- 使用Anthem.NET 1.5中的FileUpload控件实现Ajax方式的文件上传
- centOS5.5 安装 PHP APC缓存加速器
- 如何注册全部DLL文件以及DLL简要说明
- 让程序只运行一个实例(Delphi篇)
- 查询语句之带条件查询以及模糊查询