[ZOJ3213] Beautiful Meadow
插头DP。。。网格图,有障碍,格子上有权值,求总权值最大的简单路径。
因为路径的起始点不确定。。所以多开一维表示当前已经有多少个独立插头。。
只要不合并相同的联通块,并且已经用了2个独立插头,那就是一条简单路径了。。。
需要特判路径上只有一个点的情况。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int modd=,maxzt=;
struct zs1{
struct zs{
int pre;ll too;
}e[maxzt];int tot,last[modd];
int f[maxzt];ll zt[maxzt];
inline int get(ll v){
int i,x=v%modd;
for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
if(i)return i;
e[++tot].too=v,e[tot].pre=last[x],last[x]=tot,
f[tot]=,zt[tot]=v;
return tot;
}
}hm[][]; int i,j,k,n,m;
bool can[][];int val[][];
int mp[],id[];bool u[]; inline void clr(bool now,int num){
memset(hm[now][num].last,,modd<<);
hm[now][num].tot=;
}
inline void upd(int &a,int b){if(b>a)a=b;}
inline void decode(ll x){
for(int i=m;i>=;i--)mp[i]=x&,x>>=;
}
inline ll encode(){
int i,tt=;ll x=;
memset(u,,);
for(i=;i<=m;mp[i]=id[mp[i]],x=x<<|mp[i],i++)
if(!u[mp[i]]&&mp[i]>)u[mp[i]]=,id[mp[i]]=++tt;
return x;
}
inline void dp_blank(int x,int y,bool pre){
int i,left,up,f;ll zt;bool now=pre^;
for(int num=;num<=;num++){
// printf(" %d,%d %d\n",x,y,num);
clr(now,num);
for(i=;i<=hm[pre][num].tot;i++){
zt=hm[pre][num].zt[i],f=hm[pre][num].f[i];
if(y==)zt>>=;
decode(zt);
// for(int j=0;j<=m;j++)printf(" %d",mp[j]);printf(" %d zt:%lld\n",f,zt);
left=mp[y-],up=mp[y];
if(left&&up&&left!=up){
mp[y-]=mp[y]=;
for(int j=;j<=m;j++)if(mp[j]==up){mp[j]=left;break;}
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
}
if(!left&&!up){
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f );
if(can[x+][y]&&can[x][y+])
mp[y-]=mp[y]=,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
}
if((!left)^(!up)){
int j=left|up;
if(can[x+][y])
mp[y-]=j,mp[y]=,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
if(can[x][y+])
mp[y-]=,mp[y]=j,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
}
}
if(num>)
for(i=;i<=hm[pre][num-].tot;i++){
zt=hm[pre][num-].zt[i],f=hm[pre][num-].f[i];
if(y==)zt>>=;
decode(zt);
// for(int j=0;j<=m;j++)printf(" %d",mp[j]);printf(" (dl) %d zt:%lld\n",f,zt);
left=mp[y-],up=mp[y];
if(!left&&!up){
if(can[x+][y])
mp[y-]=,mp[y]=,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
if(can[x][y+])
mp[y-]=,mp[y]=,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );//,printf(" %lld %d\n",encode(),y);
}
if((!left)^(!up))
mp[y-]=mp[y]=,
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
}
}
}
inline void dp_bar(int x,int y,bool pre){
int i,left,up,f;ll zt;bool now=pre^;
for(int num=;num<=;num++){
clr(now,num);
for(i=;i<=hm[pre][num].tot;i++){
zt=hm[pre][num].zt[i],f=hm[pre][num].f[i];
if(y==)zt>>=;
decode(zt),
left=mp[y-],up=mp[y];
if(!left&&!up)
upd( hm[now][num].f[ hm[now][num].get(encode()) ] , f+val[x][y] );
}
}
} int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
}
int main(){
for(int T=read();T;T--){
n=read(),m=read();
memset(can,,sizeof(can));
int ans=;
for(i=;i<=n;i++)for(j=;j<=m;j++)val[i][j]=read(),can[i][j]=val[i][j]!=,ans=max(ans,val[i][j]);
bool pre=,now=;
clr(pre,),clr(pre,),clr(pre,);
hm[pre][].f[ hm[pre][].get() ]=;
for(i=;i<=n;i++)for(j=;j<=m;j++,swap(pre,now))
if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
for(i=;i<=hm[pre][].tot;i++)
upd(ans,hm[pre][].f[i]);
printf("%d\n",ans);
}
return ;
}
[ZOJ3213] Beautiful Meadow的更多相关文章
- zoj 2850 Beautiful Meadow
Beautiful Meadow Time Limit: 2 Seconds Memory Limit: 65536 KB Tom's Meadow Tom has a meadow in ...
- ZOJ 3213 Beautiful Meadow 简单路径 插头DP
简单路径的题目,其实就是在状态后面多记了有多少个独立插头. 分类讨论独立插头: 1.只存在上插头或者左插头,可以选择作为独立插头. 2.都不存在上插头和左插头,选择作为独立插头的同时要标号为新的连通块 ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- 杭电ACM分类
杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...
- 插头dp的几个模板
/* ural1519 求经过全部可行点的哈密顿回路的个数 括号匹配法,转移有点复杂,可是时间空间比較小 */ #include<cstdio> #include<cstring&g ...
- DP:0
小故事: A * "1+1+1+1+1+1+1+1 =?" * A : "上面等式的值是多少" B : *计算* "8!" A *在上面等式 ...
- 转载:hdu 题目分类 (侵删)
转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...
- ZOJ 2850和ZOJ 1414
下午上数据结构,结果竟然没有新题.T T果断上OJ来水一发 ZOJ 2850 Beautiful Meadow 传送门http://acm.zju.edu.cn/onlinejudge/showP ...
- 使用Beautiful Soup编写一个爬虫 系列随笔汇总
这几篇博文只是为了记录学习Beautiful Soup的过程,不仅方便自己以后查看,也许能帮到同样在学习这个技术的朋友.通过学习Beautiful Soup基础知识 完成了一个简单的爬虫服务:从all ...
随机推荐
- Python 项目实践二(生成数据)第二篇之随机漫步
接着上节继续学习,在本节中,我们将使用Python来生成随机漫步数据,再使用matplotlib以引人瞩目的方式将这些数据呈现出来.随机漫步是这样行走得到的路径:每次行走都完全是随机的,没有明确的方向 ...
- Visual Studio Code 快捷键大全(Windows)
Visual Studio Code 是一款优秀的编辑器,非常适合编写 TS 以及 React .最近在学习 AngularJs 2,开始使用 VSCode,特意整理翻译了一下官网的快捷键.因为已经习 ...
- button的用法
C# 如何去掉button按钮的边框线? 设置FlatStyle为Flat,并且设置FlatAppearance下的BorderSize为0.
- 点分治X2
1.聪聪可可 点分治板子 然而想那个 t1[1]*t1[2]*2+t1[0]*t1[0]想了好久 就是最基本的组合方法 毕竟(2,5)和(5,2)可是要算两次的 画画图就好了 (不要像我一样盯着大佬们 ...
- 搭建eclipse+tomcat开发环境
JDK 1.6 Eclipse IDE For JEE Version Tomcat 6.0 tomcatPluginV33 //eclipse平台上的插件,但它并不是tomcat本身,需要安装独立 ...
- [解决方案]WebAPI+SwaggerUI部署服务器后,访问一直报错的问题
项目的背景:制作一批接口用来给前台app或者网站提供服务,因为WebApi是最近几年来比较流行和新颖的开发接口的方式,而且又属于轻型应用,所以选用它 部署的过程:建立了WebAPI项目并使用Swagg ...
- Android测试:Building Local Unit Tests
原文:https://developer.android.com/training/testing/unit-testing/local-unit-tests.html 如果你的单元测试没有依赖或者只 ...
- Linux发行版 CentOS6.5 修改默认主机名
修改前准备 我们将主机名修改为comexchan.cnblogs.com(本文发布于http://comexchan.cnblogs.com/) 备份相关配置文件,以便回滚 cp /etc/sysco ...
- Tomcat安装和目录简介
要知道动态的网页必须要有服务器的支撑! 1.知名的java web服务器 Tomcat:Apache组织发布,免费开源的,轻量级 JBoss.WebLogic是商用的,价格较高,但相对于开源的更加稳定 ...
- Git详解之一:Git起步
起步 本章介绍开始使用 Git 前的相关知识.我们会先了解一些版本控制工具的历史背景,然后试着让 Git 在你的系统上跑起来,直到最后配置好,可以正常开始开发工作.读完本章,你就会明白为什么 Git ...