【题目大意】

在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]神奇游乐园的更多相关文章

  1. [bzoj1187][HNOI2007]神奇游乐园_插头dp

    bzoj-1187 HNOI-2007 神奇游乐园 题目大意:经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这 ...

  2. BZOJ1187 [HNOI2007]神奇游乐园(插头dp)

    麻麻我会写插头dp了! 推荐陈丹琦论文:https://wenku.baidu.com/view/3e90d32b453610661ed9f4bd.html 破题调一年 #include <cs ...

  3. [bzoj1187][HNOI2007]神奇游乐园

    来自FallDream的博客,未经允许,请勿转载,谢谢, 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一 ...

  4. 【BZOJ1187】[HNOI2007]神奇游乐园 插头DP

    [BZOJ1187][HNOI2007]神奇游乐园 Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细 ...

  5. bzoj 1187: [HNOI2007]神奇游乐园 插头dp

    1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 668  Solved: 337[Submit][Statu ...

  6. 洛谷 P3190 [HNOI2007]神奇游乐园 解题报告

    P3190 [HNOI2007]神奇游乐园 Description 给你一个 \(m * n\) 的矩阵,每个矩阵内有个权值\(V(i,j)\) (可能为负数),要求找一条回路,使得每个点最多经过一次 ...

  7. [HNOI2007]神奇游乐园(插头DP)

    题意:n*m的矩阵内值有正有负,找一个四连通的简单环(长度>=4),使得环上值的和最大. 题解:看到2<=m<=6和简单环,很容易想到插头DP,设f[i][j][k]表示轮廓线为第i ...

  8. 洛谷P3190 [HNOI2007]神奇游乐园(插头dp)

    传送门 大概是算第一道自己做出来的插头dp? (虽然都是照着抄板子的) (虽然有个地方死活没调出来最后只能看题解才发现自己错在哪里的) 我就当你们都会插头dp了…… 因为必须得是一条路径,所以扫描线上 ...

  9. 【bzoj1187】 HNOI2007—神奇游乐园

    http://www.lydsy.com/JudgeOnline/problem.php?id=1187 (题目链接) 题意 一个$n*m$的矩阵,其中每一个位置有一个权值,求一条回路使得经过的位置的 ...

随机推荐

  1. 面向对象 ( OO ) 的程序设计——理解对象

    本文地址:http://www.cnblogs.com/veinyin/p/7607938.html  1 创建自定义对象 创建自定义对象的最简单方法为创建 Object 的实例,并添加属性方法,也可 ...

  2. Spring Session加Redis

    session是一个非常常见的概念.session的作用是为了辅助http协议,因为http是本身是一个无状态协议.为了记录用户的状态,session机制就应运而生了.同时session也是一个非常老 ...

  3. Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)

    题目链接:https://www.spoj.com/problems/COT/en/ 题目: 题意: 给你一棵有n个节点的树,求节点u到节点v这条链上的第k大. 思路: 我们首先用dfs进行建题目给的 ...

  4. 前端bootstrap框架禁用响应式的方法

    在Bootstrap中极其重要的一个技术内容便是响应式布局了,一次编码针对不同设备终端的强大能力使得响应式技术愈发流行. 不过正所谓“萝卜青菜各有所爱”,如果你想要使用Bootstrap开发自己的项目 ...

  5. dpkg的用法 (转)

    dpkg是一个Debian的一个命令行工具,它可以用来安装.删除.构建和管理Debian的软件包. 下面是它的一些命令解释: 1)安装软件 命令行:dpkg -i <.deb file name ...

  6. module 'pytest' has no attribute 'allure'问题解决

    安装allure后执行命令后报错module 'pytest' has no attribute 'allure' C:\Users\Desktop\xin>pytest -s -q --all ...

  7. Keras自定义评估函数

    1. 比较一般的自定义函数: 需要注意的是,不能像sklearn那样直接定义,因为这里的y_true和y_pred是张量,不是numpy数组.示例如下: from keras import backe ...

  8. openjudge-NOI 2.6-2718 移动路线

    题目链接:http://noi.openjudge.cn/ch0206/2718/ 题解: 递推,某一个点只能从其左边或者下边走过来 f[i][j]存储(i,j)这个点上的结果,即f[i][j]=f[ ...

  9. VirtualBox与Genymotion命令行启动

    一.VirtualBox命令行启动 1.添加环境变量: %programfiles%\Oracle\VirtualBox 2.用VBoxManage查看已存在vmname|uuid命令: VBoxMa ...

  10. Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f070058 android-studio 3.0 from canary 5 to canary 6

    我升级android-studio到了3.0 canary 6打包编译安装出现如下错误: 07-11 13:00:39.523 8913-8913/dcpl.com.myapplication E/A ...