[ZOJ3213] Beautiful Meadow

  插头DP。。。网格图,有障碍,格子上有权值,求总权值最大的简单路径。

  因为路径的起始点不确定。。所以多开一维表示当前已经有多少个独立插头。。

  只要不合并相同的联通块,并且已经用了2个独立插头,那就是一条简单路径了。。。

  需要特判路径上只有一个点的情况。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define ll long long
  6 using namespace std;
  7 const int modd=5233,maxzt=123333;
  8 struct zs1{
  9     struct zs{
 10         int pre;ll too;
 11     }e[maxzt];int tot,last[modd];
 12     int f[maxzt];ll zt[maxzt];
 13     inline int get(ll v){
 14         int i,x=v%modd;
 15         for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
 16         if(i)return i;
 17         e[++tot].too=v,e[tot].pre=last[x],last[x]=tot,
 18         f[tot]=0,zt[tot]=v;
 19         return tot;
 20     }
 21 }hm[2][3];
 22 
 23 int i,j,k,n,m;
 24 bool can[23][23];int val[23][23];
 25 int mp[9],id[9];bool u[9];
 26 
 27 inline void clr(bool now,int num){
 28     memset(hm[now][num].last,0,modd<<2);
 29     hm[now][num].tot=0;
 30 }
 31 inline void upd(int &a,int b){if(b>a)a=b;}
 32 inline void decode(ll x){
 33     for(int i=m;i>=0;i--)mp[i]=x&7,x>>=3;
 34 }
 35 inline ll encode(){
 36     int i,tt=0;ll x=0;
 37     memset(u,0,9);
 38     for(i=0;i<=m;mp[i]=id[mp[i]],x=x<<3|mp[i],i++)
 39         if(!u[mp[i]]&&mp[i]>0)u[mp[i]]=1,id[mp[i]]=++tt;
 40     return x;
 41 }
 42 inline void dp_blank(int x,int y,bool pre){
 43     int i,left,up,f;ll zt;bool now=pre^1;
 44     for(int num=0;num<=2;num++){
 45 //        printf("    %d,%d %d\n",x,y,num);
 46         clr(now,num);
 47         for(i=1;i<=hm[pre][num].tot;i++){
 48             zt=hm[pre][num].zt[i],f=hm[pre][num].f[i];
 49             if(y==1)zt>>=3;
 50             decode(zt);
 51 //            for(int j=0;j<=m;j++)printf(" %d",mp[j]);printf("    %d    zt:%lld\n",f,zt);
 52             left=mp[y-1],up=mp[y];
 53             if(left&&up&&left!=up){
 54                 mp[y-1]=mp[y]=0;
 55                 for(int j=0;j<=m;j++)if(mp[j]==up){mp[j]=left;break;}
 56                 upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 57             }
 58             if(!left&&!up){
 59                 upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f );
 60                 if(can[x+1][y]&&can[x][y+1])
 61                     mp[y-1]=mp[y]=7,
 62                     upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 63             }
 64             if((!left)^(!up)){
 65                 int j=left|up;
 66                 if(can[x+1][y])
 67                     mp[y-1]=j,mp[y]=0,
 68                     upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 69                 if(can[x][y+1])
 70                     mp[y-1]=0,mp[y]=j,
 71                     upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 72             }
 73         }
 74         if(num>0)
 75             for(i=1;i<=hm[pre][num-1].tot;i++){
 76                 zt=hm[pre][num-1].zt[i],f=hm[pre][num-1].f[i];
 77                 if(y==1)zt>>=3;
 78                 decode(zt);
 79 //                for(int j=0;j<=m;j++)printf(" %d",mp[j]);printf("    (dl) %d   zt:%lld\n",f,zt);
 80                 left=mp[y-1],up=mp[y];
 81                 if(!left&&!up){
 82                     if(can[x+1][y])
 83                         mp[y-1]=7,mp[y]=0,
 84                         upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 85                     if(can[x][y+1])
 86                         mp[y-1]=0,mp[y]=7,
 87                         upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );//,printf("   %lld %d\n",encode(),y);
 88                 }
 89                 if((!left)^(!up))
 90                     mp[y-1]=mp[y]=0,
 91                     upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
 92             }
 93     }
 94 }
 95 inline void dp_bar(int x,int y,bool pre){
 96     int i,left,up,f;ll zt;bool now=pre^1;
 97     for(int num=0;num<=2;num++){
 98         clr(now,num);
 99         for(i=1;i<=hm[pre][num].tot;i++){
100             zt=hm[pre][num].zt[i],f=hm[pre][num].f[i];
101             if(y==1)zt>>=3;
102             decode(zt),
103             left=mp[y-1],up=mp[y];
104             if(!left&&!up)
105                 upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
106         }
107     }
108 }
109 
110 int ra;char rx;
111 inline int read(){
112     rx=getchar(),ra=0;
113     while(rx<'0'||rx>'9')rx=getchar();
114     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
115 }
116 int main(){
117     for(int T=read();T;T--){
118         n=read(),m=read();
119         memset(can,0,sizeof(can));
120         int ans=0;
121         for(i=1;i<=n;i++)for(j=1;j<=m;j++)val[i][j]=read(),can[i][j]=val[i][j]!=0,ans=max(ans,val[i][j]);
122         bool pre=0,now=1;
123         clr(pre,0),clr(pre,1),clr(pre,2);
124         hm[pre][0].f[ hm[pre][0].get(0) ]=0;
125         for(i=1;i<=n;i++)for(j=1;j<=m;j++,swap(pre,now))
126             if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
127         for(i=1;i<=hm[pre][2].tot;i++)
128             upd(ans,hm[pre][2].f[i]);
129         printf("%d\n",ans);
130     }
131     return 0;
132 }
View Code

 

转载于:https://www.cnblogs.com/czllgzmzl/p/5495227.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值