[HNOI2007]神奇游乐园
Description:
在方格图上找一条回路使经过的权值最小
Hint:
\(n<=100,m<=6\)
Solution:
一开始又看错题了。。。稍有细节的水题,详见代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mxn=102,c[4]={0,-1,1,0};
struct data {
int key; ll val;
};
int n,m,t,ex,ey;
int g[mxn][mxn];
char mp[mxn][mxn];
ll ans=-100000000;
unordered_map<int ,data > dp[3];
map<int , int > vis;
typedef unordered_map<int ,data >::iterator uit;
inline void copy(data x,int id) {dp[id][x.key<<2]=(data){x.key<<2,x.val};}
inline int get(int st,int x) {x<<=1; return (st>>x)&3;}
inline int md(int st,int x,int val) {x<<=1; return (st&(~(3<<x)))|(val<<x);}
inline int getl(int st,int x) {
int l=x,cnt=1;
while(cnt!=0) cnt+=c[get(st,--l)];
return l;
}
inline int getr(int st,int x) {
int r=x,cnt=-1;
while(cnt!=0) cnt+=c[get(st,++r)];
return r;
}
inline void update(int x,int y,data d)
{
int st=d.key; ll val=d.val;
int p=get(st,y),q=get(st,y+1);
if(p==0&&q==0) {
if(vis[st])
dp[t^1][st]=(data){st,max(dp[t^1][st].val,val)};
else dp[t^1][st]=(data){st,val},vis[st]=1;
if(x==n-1||y==m-1) return ;
int nst=md(st,y,1); nst=md(nst,y+1,2);
if(vis[nst]) dp[t^1][nst]=(data){nst,max(dp[t^1][nst].val,val+g[x][y])}; //由于map不能赋初值,故另外使用vis来记录状态有无
else dp[t^1][nst]=(data){nst,val+g[x][y]},vis[nst]=1;
return ; //不要少写return
}
if(p==0||q==0) {
if(y<m-1) {
int nst=md(st,y,0); nst=md(nst,y+1,p+q);
if(vis[nst])
dp[t^1][nst]=(data){nst,max(dp[t^1][nst].val,val+g[x][y])};
else dp[t^1][nst]=(data){nst,val+g[x][y]},vis[nst]=1;
}
if(x<n-1) {
int nst=md(st,y,p+q); nst=md(nst,y+1,0);
if(vis[nst])
dp[t^1][nst]=(data){nst,max(dp[t^1][nst].val,val+g[x][y])};
else dp[t^1][nst]=(data){nst,val+g[x][y]},vis[nst]=1;
}
return ;
}
int nst=md(st,y,0); nst=md(nst,y+1,0);
if(p==1&&q==1) nst=md(nst,getr(st,y+1),1);
if(p==2&&q==2) nst=md(nst,getl(st,y),2);
if(p==1&&q==2) {
st=md(st,y,0),st=md(st,y+1,0);
if(!st) //为了保证只有一条路径
ans=max(ans,val+g[x][y]);
return ;
}
if(vis[nst])
dp[t^1][nst]=(data){nst,max(dp[t^1][nst].val,val+g[x][y])};
else dp[t^1][nst]=(data){nst,val+g[x][y]},vis[nst]=1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
scanf("%d",&g[i][j]);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
mp[i][j]='.';
ex=n-1,ey=m-1;
t=0;
dp[t][0]=(data){0,0};
for(int i=0;i<n;++i) {
dp[2].clear();
for(uit j=dp[t].begin();j!=dp[t].end();++j) copy((*j).second,2);
dp[t].clear();
for(uit j=dp[2].begin();j!=dp[2].end();++j) dp[t][(*j).second.key]=(*j).second;
for(int j=0;j<m;++j) {
dp[t^1].clear(); vis.clear();
for(uit k=dp[t].begin();k!=dp[t].end();++k)
update(i,j,(*k).second);
t^=1;
}
}
printf("%lld",ans);
return 0;
}
[HNOI2007]神奇游乐园的更多相关文章
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 668 Solved: 337[Submit][Statu ...
- 【BZOJ1187】[HNOI2007]神奇游乐园 插头DP
[BZOJ1187][HNOI2007]神奇游乐园 Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细 ...
- 洛谷 P3190 [HNOI2007]神奇游乐园 解题报告
P3190 [HNOI2007]神奇游乐园 Description 给你一个 \(m * n\) 的矩阵,每个矩阵内有个权值\(V(i,j)\) (可能为负数),要求找一条回路,使得每个点最多经过一次 ...
- [bzoj1187][HNOI2007]神奇游乐园_插头dp
bzoj-1187 HNOI-2007 神奇游乐园 题目大意:经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这 ...
- 1187: [HNOI2007]神奇游乐园 - BZOJ
Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一个游乐场,专为旅途中疲惫的人设计. ...
- bzoj:1187: [HNOI2007]神奇游乐园
Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一个游乐场,专为旅途中疲惫的人设计. ...
- [bzoj1187][HNOI2007]神奇游乐园
来自FallDream的博客,未经允许,请勿转载,谢谢, 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一 ...
- BZOJ1187 [HNOI2007]神奇游乐园(插头dp)
麻麻我会写插头dp了! 推荐陈丹琦论文:https://wenku.baidu.com/view/3e90d32b453610661ed9f4bd.html 破题调一年 #include <cs ...
- [HNOI2007]神奇游乐园(插头DP)
题意:n*m的矩阵内值有正有负,找一个四连通的简单环(长度>=4),使得环上值的和最大. 题解:看到2<=m<=6和简单环,很容易想到插头DP,设f[i][j][k]表示轮廓线为第i ...
随机推荐
- C程序的内存分配及动态内存
1.程序内存的分配 一个由C/C++编译的程序占用的内存分为以下几个部分:1)栈区(stack) — 由编译器自动分配释放 , 存放为运行函数而分配的局部变量. 函数参数. 返回数据. 返回地址等. ...
- unzip文件解压
1.记录下,遇到.zip的安装包,指定解压到某个地方 格式:unzip 压缩包名.zip -d 存放路径
- DNS解析中的A记录、AAAA记录、CNAME记录、MX记录、NS记录、TXT记录、SRV记录、URL转发等
AA记录: 将域名指向一个IPv4地址(例如:100.100.100.100),需要增加A记录 NSNS记录: 域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录 SOASO ...
- spring的4种事务特性,5种隔离级别,7种传播行为
spring事务: 事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种): 原子性 (atomicity):强调事务的不可分割. 一致性 (con ...
- linux shell基本知识
shell script的一些注意事项: .#这个符号是注释本行,通常用来做批注用,#!除外,是用来标注用哪种shell执行本脚本, .执行顺序为从上到下,从做到右 .忽略空行,tab空格 .脚本换行 ...
- file标签 - 图片上传前预览 - FileReader & 网络图片转base64和文件流
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
- git之二: git可视化工具sourcetree
参考: https://www.cnblogs.com/tian-xie/p/6264104.html sourcetree安装使用
- Vue全局API总结
1.extend用于创建一个子类Vue,用$mount来挂载 <body> <div id="app"></div> <script> ...
- Collection接口的常用方法
[添加功能] boolean add(Object obj); //添加一个元素. boolean addAll(Collection c); //添加一个集合的元素(在后面追加). [删除功能] v ...
- 20165235 2018-3 《Java程序设计》第5周学习总结
20165235 2018-3 <Java程序设计>第5周学习总结 教材学习内容总结 第六章 内部类与异常类 (一)内部类:1.java支持在一个类中定义另一个类,这个类叫内部类.2.内部 ...