【插头DP】BZOJ1187- [HNOI2007]神奇游乐园
【题目大意】
在n*m的网格中选一条回路,使权值和最大。
【思路】
和之前裸的插头DP差不多,只不过现在回路不需要经过所有的格子。所以有以下几个注意点(具体看注释):
(1)left和up插头相等的时候,直接更新答案;
(2)left和up插头不存在的时候,还要考虑当前格子不取的情况。
orz写了半天,感觉被掏空.jpg
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=;
const int MAXM=;
const int HASH=;
const int INF=0x7fffffff;
ll ans=-1ll << ;
int n,m,sat[MAXM][MAXN];
int code[MAXN]; struct HashMap
{
vector<int> hash[HASH];
vector<ll> state,f; void clear()
{
for(int i=;i<HASH;i++) vector<int>().swap(hash[i]);
vector<ll>().swap(state);
vector<ll>().swap(f);
} void push(ll st,ll ans)
{
int h=st%HASH;
for (int i=;i<hash[h].size();i++)
{
int now=hash[h][i];
if (state[now]==st)
{
f[now]=max(f[now],ans);
return;
}
}
state.push_back(st);
f.push_back(ans);
hash[h].push_back(state.size()-);
}
}dp[]; void decode(ll state)
{
memset(code,,sizeof(code));
for (int i=n;i>=;i--)
{
code[i]=state&;
state>>=;
}
} void shift()
{
for (int i=n;i>;i--) code[i]=code[i-];
code[]=;
} ll encode()
{
int ch[MAXN],cnt=;
memset(ch,-,sizeof(ch));
ch[]=;
ll ret=;
for (int i=;i<=n;i++)
{
if (ch[code[i]]==-) ch[code[i]]=++cnt;
code[i]=ch[code[i]];
ret<<=;
ret|=code[i];
}
return ret;
} void dpblank(int i,int j,int cur)
{
for (int k=;k<dp[-cur].state.size();k++)
{
decode(dp[-cur].state[k]);
if (j==)//把之前shift的写法改成这样写了,总之就过了,也不知道为什么orz
{
if (code[n]) continue;
shift();
}
int left=code[j-],up=code[j]; if (left && up)
{
code[j-]=code[j]=;
if (left==up)
{
if (encode()==) ans=max(ans,dp[-cur].f[k]+sat[i][j]);
//注意和之前不一样的地方:如果已经封闭起来了就更新答案
}
else
{
for (int t=;t<=n;t++) if (code[t]==left) code[t]=up;
dp[cur].push(encode(),dp[-cur].f[k]+sat[i][j]);
}
} if ((left && (!up)) || (up && (!left)))
{
int t=left|up;
code[j-]=;
code[j]=t;
dp[cur].push(encode(),dp[-cur].f[k]+sat[i][j]);
code[j-]=t;
code[j]=;
dp[cur].push(encode(),dp[-cur].f[k]+sat[i][j]);
} if (!left && !up)
{
dp[cur].push(encode(),dp[-cur].f[k]);
//注意并不一定是所有格子都要经过,所以还要考虑不经过当前格子的情况
code[j-]=code[j]=MAXN-;
dp[cur].push(encode(),dp[-cur].f[k]+sat[i][j]);
}
}
} void init()
{
scanf("%d%d",&m,&n);
for (int i=;i<=m;i++)
for (int j=;j<=n;j++) scanf("%d",&sat[i][j]);
} void solve()
{
int cur=;
dp[cur].clear();
dp[cur].push(,);
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)
{
cur^=;
dp[cur].clear();
dpblank(i,j,cur);
}
printf("%lld",ans);
} int main()
{
init();
solve();
return ;
}
【插头DP】BZOJ1187- [HNOI2007]神奇游乐园的更多相关文章
- [bzoj1187][HNOI2007]神奇游乐园_插头dp
bzoj-1187 HNOI-2007 神奇游乐园 题目大意:经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这 ...
- BZOJ1187 [HNOI2007]神奇游乐园(插头dp)
麻麻我会写插头dp了! 推荐陈丹琦论文:https://wenku.baidu.com/view/3e90d32b453610661ed9f4bd.html 破题调一年 #include <cs ...
- [bzoj1187][HNOI2007]神奇游乐园
来自FallDream的博客,未经允许,请勿转载,谢谢, 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一 ...
- 【BZOJ1187】[HNOI2007]神奇游乐园 插头DP
[BZOJ1187][HNOI2007]神奇游乐园 Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细 ...
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 668 Solved: 337[Submit][Statu ...
- 洛谷 P3190 [HNOI2007]神奇游乐园 解题报告
P3190 [HNOI2007]神奇游乐园 Description 给你一个 \(m * n\) 的矩阵,每个矩阵内有个权值\(V(i,j)\) (可能为负数),要求找一条回路,使得每个点最多经过一次 ...
- [HNOI2007]神奇游乐园(插头DP)
题意:n*m的矩阵内值有正有负,找一个四连通的简单环(长度>=4),使得环上值的和最大. 题解:看到2<=m<=6和简单环,很容易想到插头DP,设f[i][j][k]表示轮廓线为第i ...
- 洛谷P3190 [HNOI2007]神奇游乐园(插头dp)
传送门 大概是算第一道自己做出来的插头dp? (虽然都是照着抄板子的) (虽然有个地方死活没调出来最后只能看题解才发现自己错在哪里的) 我就当你们都会插头dp了…… 因为必须得是一条路径,所以扫描线上 ...
- 【bzoj1187】 HNOI2007—神奇游乐园
http://www.lydsy.com/JudgeOnline/problem.php?id=1187 (题目链接) 题意 一个$n*m$的矩阵,其中每一个位置有一个权值,求一条回路使得经过的位置的 ...
随机推荐
- 【总结】对FFT的理解 / 【洛谷 P3803】 【模板】多项式乘法(FFT)
题目链接 \(\Huge\text{无图,慎入}\) \(FFT\)即快速傅里叶变换,用于加速多项式乘法. 如果暴力做卷积的话就是一个多项式的每个单项式去乘另一个多项式然后加起来,时间复杂度为\(O( ...
- python简单爬虫一
简单的说,爬虫的意思就是根据url访问请求,然后对返回的数据进行提取,获取对自己有用的信息.然后我们可以将这些有用的信息保存到数据库或者保存到文件中.如果我们手工一个一个访问提取非常慢,所以我们需要编 ...
- juey点击tr选中里面的radio
//点击一行选中银行卡 $("tr").bind("click",function(){ $("input:radio").attr(&qu ...
- sql server 2008 r2 产品密钥
数据中心版:PTTFM-X467G-P7RH2-3Q6CG-4DMYBDDT3B-8W62X-P9JD6-8MX7M-HWK38==================================== ...
- Python 库汇总中文版
这又是一个 Awesome XXX 系列的资源整理,由 vinta 发起和维护.内容包括:Web框架.网络爬虫.网络内容提取.模板引擎.数据库.数据可视化.图片处理.文本处理.自然语言处理.机器学习. ...
- 转:google测试分享-测试经理
原文: http://blog.sina.com.cn/s/blog_6cf812be0102vode.html 前言:这个系列分享的内容大部分都是出自于<google是如何测试的>的书, ...
- PHP 面向对象 final类与final方法
final---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被 ...
- linux中的vim 编辑一行内容,如何使光标快速移动到行首和行尾以及行中间某处啊?
光标定位G 移至行行首nG 移至第n行行首n+ 移n行行首n- 移n行行首n$ 移n行(1表示本行)行尾0 所行行首$ 所行行尾^ 所行首字母h,j,k,l 左移移移右移H 前屏幕首行行首M 屏幕显示 ...
- 使用CLion
CLion是JetBrains公司的一款C++的IDE.默认使用Cmake构建. ubuntu和fedora下的安装 在ubuntu下安装了CLion,和QtCreator相比: ibus输入法能输入 ...
- webapi调用post时自动匹配参数
[HttpPost] public async Task<string> Post() { dynamic model = await Request.Content.ReadAsAsyn ...