题解:

简单的插头dp

加上一个代价即可

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,HASH=,STATE=,M=1e9+;
typedef long long ll;
int n,m,ch[N],code[N],mp[N][N],mp2[N][N];
struct HASHMAP
{
int head[HASH],next[STATE],size;
ll state[STATE],f[STATE];
void init()
{
size=;
memset(head,-,sizeof(head));
}
void push(ll st,ll ans)
{
int h=st%HASH;
for (int i=head[h];i!=-;i=next[i])
if (state[i]==st)
{
f[i]=max(ans,f[i]);
return;
}
state[size]=st;
f[size]=ans;
next[size]=head[h];
head[h]=size++;
}
}hm[];
void decode(ll st)
{
for (int i=m;i>=;i--)
{
code[i]=st&;
st>>=;
}
}
ll encode()
{
int cnt=;
ll st=;
memset(ch,-,sizeof(ch));
ch[]=;ch[]=;
for (int i=;i<=m;i++)
{
if (ch[code[i]]==-)ch[code[i]]=cnt++;
code[i]=ch[code[i]];
st<<=;
st|=code[i];
}
return st;
}
void shift()
{
for (int i=m;i;i--)code[i]=code[i-];
code[]=;
}
void dp(int r,int c,int cur)
{
for (int k=;k<hm[cur].size;k++)
{
decode(hm[cur].state[k]);
int up=code[c],left=code[c-];
if ((r==&&c==)||(r==n&&c==m))
{
if (!up&&!left)
{
if (c<m)
{
code[c]=;
code[c-]=;
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
if (r<n)
{
code[c]=;
code[c-]=;
if (m==c)shift();
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
}
if (up||left)
{
code[c]=code[c-]=;
if (m==c)shift();
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
continue;
}
if (up&&left)
{
if (up!=left)
{
int t=max(up,left);
code[c]=code[c-]=;
for (int i=;i<=m;i++)
if (code[i]==left||code[i]==up)code[i] = t;
if (m==c) shift();
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
}
else if (up||left)
{
if (c<m)
{
code[c-]=;
code[c]=up|left;
if (m==c)shift();
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
if (r<n)
{
code[c-]=up|left;
code[c]=;
if (m==c) shift();
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
}
else
{
if (c<m&&r<n)
{
code[c-]=code[c]=;
hm[cur^].push(encode(),hm[cur].f[k]+mp[r][c]);
}
code[c]=code[c-]=;
if (c==m) shift();
hm[cur^].push(encode(),hm[cur].f[k]);
}
}
}
int main()
{
int cas=;
while (~scanf("%d%d",&n,&m))
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)scanf("%d", &mp[i][j]);
if (n==&&m==)
{
printf("Case %d: %d\n",++cas,mp[][]);
continue;
}
if (n<m)
{
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)mp2[i][j]=mp[j][i];
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)mp[i][j]=mp2[i][j];
swap(n,m);
}
int cur=;
hm[cur].init();
hm[cur].push(,);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
hm[cur^].init();
dp(i,j,cur);
cur^=;
}
ll ans=-1e18;
for (int i=;i<hm[cur].size;i++)ans=max(ans,hm[cur].f[i]);
printf("Case %d: %lld\n",++cas,ans);
}
return ;
}

hdu3377的更多相关文章

  1. HDU3377 Plan

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3377 简单路径要求权值最大,那么为了回避括号序列单独插头的情况特判多,考虑使用最小表示法. #incl ...

  2. 2019.01.23 hdu3377 Plan(轮廓线dp)

    传送门 题意简述:给一个n*m的带权矩阵,求从左上角走到右下角的最大分数,每个格子只能经过最多一次,n,m≤9n,m\le9n,m≤9. 思路: 考虑轮廓线dpdpdp,但这道题并没有出现回路的限制因 ...

  3. hdu3377之简单路径求最值

    Plan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. 初探插头dp

    开学那个月学了点新东西,不知道还记不记得了,mark一下 感觉cdq的论文讲的很详细 题主要跟着kuangbin巨做了几道基础的 http://www.cnblogs.com/kuangbin/arc ...

随机推荐

  1. mint fcitx搜狗输入法不显示输入框,其他输入法丢失皮肤

    mint18.3 因为这个原因刚刚重装过,结果一不留神又这样了. 这次原因相对清晰: 双屏显示下,合屏睡眠,打开之后,发现卡死了.屏幕分辨率改变了似的. 然后再重启,发现输入法悬浮框变大了,然后输入法 ...

  2. Codeforces 551 E - GukiZ and GukiZiana

    E - GukiZ and GukiZiana 思路:分块, 块内二分 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC ...

  3. JAVA基础知识总结:十六

    一.File类 主要用于文件操作 对存储在磁盘上的文件和目录的抽取和封装 二.IO流 1.概念 File类只能创建或者修改文件或者文件夹的层级结构,如果要访问文件中的内容的话,就需要用到IO流(Inp ...

  4. vue-循环标记列表元素

    <el-col :lg="4" class="list" v-for="(item,index) in picList"> &l ...

  5. js判断手指的上滑,下滑,左滑,右滑,事件监听

    原理:1:当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和staerY: 2:当触发touchmove事件的时候,再获取此时手指的横坐标moveEndX和纵坐标moveEn ...

  6. mac软件

    1. http://www.ifunmac.com/ 2.Mac安装软件时提示已损坏的解决方法 http://www.jianshu.com/p/3d04a2292fcd 3.mac以后有时间在装的软 ...

  7. centos7【防火墙】常用规则

    1.防火墙常用规则 systemctl start iptables systemctl stop iptables systemctl restart iptablesiptables -nvL 1 ...

  8. HTML如何实现滚动文字

    HTML如何实现滚动文字 一.总结 一句话总结:marquee标签,也可以用js和css来实现 marquee标签 也可jss和css <marquee><span style=&q ...

  9. R quantile函数 | cut函数 | sample函数 | all函数 | scale函数 | do.call函数

    取出一个数字序列中的百分位数 1. 求某一个百分比 x<-rnorm(200) quantile(x,0.9) 2. 求一系列的百分比 quantile(x,c(0.1,0.9)) quanti ...

  10. python3-知识扩展扫盲易忘-zip的用法

    >>>a = [1,2,3] >>> b = [4,5,6]>>> c = [4,5,6,7,8]>>> zipped = zi ...