[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 ...
随机推荐
- go编程之常见工具函数
1.时间格式化 基于模式的布局进行时间格式化和解析 package main import "fmt" import "time" func main() { ...
- IntelliJ IDEA如何设置头注释,自定义author和date
下面这张图,保证你一看就会: 下面这个模板,你拿去改一改就行了. /** * @Author: Gosin * @Date: ${DATE} ${TIME} */ 如果觉得上面名字下面的波浪线碍眼,可 ...
- 浅析 SpringMVC 原理和配置.
一.原理 Spring MVC基于模型-视图-控制器(Model-View-Controller,MVC)模式实现,它能够帮你构建像Spring框架那样灵活和松耦合的Web应用程序,将请求处理的逻辑和 ...
- bootstrap html页面禁止放大缩小
用bootstrap写的html页面,在手机端中禁止放大缩小: 亲测有效: <meta name="viewport" content="width=device- ...
- Mockplus设计大赛获奖选手专访 | High音:轻松生活,随心嗨音
"看似低调,实则高调的设计,UI设计是用了功力,主页功能和内容一览无余,方便用户选择,金字黑底,给予用户极好的奢华体验.原来听歌也是一种视觉享受.创新性源于对听歌氛围的把握,大幅的图片,刺激 ...
- Yum database disk image is malformed
使用 yum update 时使用Ctrl+C 后,再用yum 安装其他软件的时候收到:Yum database disk image is malformedyum clean dbcache 清除 ...
- java小技术之生成二维码
把我们需要的链接或者内容生成二维码其实是一件非常容易的事情,有很多办法可以实现,这里我们采用JS方法生成. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTM ...
- ConcurrentHashMap 从Java7 到 Java8的改变
一.关于分段锁 集合框架很大程度减少了java程序员的重复劳动,然而,在Java多线程环境中,以线程安全的方式使用集合类是一个首先考虑的问题. 越来越多的程序员了解到了ConcurrentHashMa ...
- linux防火墙之 ufw
Usage: ufw COMMAND Commands: enable enables the firewall 开启ufw防火墙 disable disables the firewall 禁用防火 ...
- DCL的失效:现实与初衷的背离
最近看了Brian Goetz写的一篇有关DCL的文章:Double-checked locking: Clever, but broken.( 2001年发表于JavaWorld上) 这篇文章讲述了 ...