【题目大意】

在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. hihoCoder 1174 : 拓扑排序·一

    题目链接:http://hihocoder.com/problemset/problem/1174 题目是中文题面我就不说题意了,要看题面的请点击上方链接~ 代码实现如下: #include < ...

  2. NYOJ 221 Tree (二叉树)

    题目链接 描述 Little Valentine liked playing with binary trees very much. Her favorite game was constructi ...

  3. 29、最小的K个数

    一.题目 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解法 import java.util.ArrayList; ...

  4. flask基础之jijia2模板使用基础(二)

    前言 在以前前后端不分离的时代,后台程序员往往又当爹又当妈,需要将前端程序员写的h5页面填充模板语言.而jijia2是一门十分强大的python的模板语言,是flask框架的核心模块之一.先简单介绍一 ...

  5. [006] largest_common_substring

    [Description] Given two different strings, find the largest successive common substring. e.g. str1[] ...

  6. 10.python3标准库--加密

    ''' 加密可以保护消息安全,以便验证其正确性并保护消息不被截获. python的加密支持包括hashlib和hmac,hashlib使用标准算法生成消息内容签名,hmac则用于验证消息在传输过程中未 ...

  7. Nginx-1.6.3源码安装、虚拟主机

    源码安装nginx cat /etc/redhat-release uname -rm yum install pcre-devel openssl-devel -y rpm -qa pcre pcr ...

  8. java基础9 main函数、this、static、super、final、instanceof 关键字

    一.main函数详解 1.public:公共的.权限是最大的,在任何情况都可以访问  原因:为了保证jvm在任何情况下都可以访问到main法2.static:静态,静态可以让jvm调用更方便,不需要用 ...

  9. C++中对已分配空间的指针调用一个类的构造函数

    在看MINIBASE的源代码的时候发现里面有类似于这样的东西 bufTable = (BufDesc*) MINIBASE_SHMEM->malloc( numBuffers * sizeof( ...

  10. function(函数)中的动态参数

    我们可向函数传递动态参数,*args,**kwargs,首先我们来看*args,示例如下:     1.show(*args) def show(*args): print(args,type(arg ...