插头DP


  sigh……其实思路很简单的= =就多加一种转移:从(0,0)->(0,0),也就是不走这个格子……

  初始状态就是第一格有一个左插头= =结束状态可以让(n,m)这个位置可以走到(n+1,m),这样就符合题意了= =

  然后一个大坑出现:

    转移时不能随意修改sum值!!因为一个状态两次转移的话,第一次修改了sum值,第二次的转移就会出错!!

    http://blog.csdn.net/xingyeyongheng/article/details/24499375 我还是看了这篇博客才幡然醒悟!

 //BZOJ 3377
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define CC(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e7+,INF=~0u>>;
const double eps=1e-;
/*******************template********************/
const int M=;
typedef long long LL;
int mp[][];
bool mmp[][];
int n,m,k;
int tot[],bit[],hash[M],state[][M];
LL dp[][M],ans; void init(){
CC(mp,);
CC(mmp,);
char ch;
F(i,,n) F(j,,m) {scanf("%d",&mp[i][j]); mmp[i][j]=;}
mmp[n+][m]=;
F(i,,) F(j,,M-) dp[i][j]=-INF;
tot[]=; ans=-INF;
k=;
dp[][]=mp[][];
state[][]=;
}
void hash_in(int s,LL sum){
int p=s%M;
while(hash[p]){
if (state[k][hash[p]]==s){
dp[k][hash[p]]=max(dp[k][hash[p]],sum);
return;
}
p++;
if (p==M) p=;
}
hash[p]=++tot[k];
state[k][hash[p]]=s;
dp[k][hash[p]]=sum;
}
#define in hash_in(s,sum)
void work(){
F(i,,n){
F(j,,m){
k^=;
tot[k]=;
CC(hash,);
F(u,,tot[-k]){
int s=state[-k][u];
LL sum=dp[-k][u];
int p=(s>>bit[j-])&,q=(s>>bit[j])&,d=(s>>bit[j+])&;
if (!p && !q){
in;
if (!mmp[i+][j] || !mmp[i][j+]) continue;
s=s^(<<bit[j-])^(<<bit[j]<<);
sum=sum+mp[i][j]+mp[i+][j];
if (!d) sum+=mp[i][j+];
in;
}else if(!p && q){
if (mmp[i][j+]){
// if (!d) sum+=mp[i][j+1];
if (!d) hash_in(s,sum+mp[i][j+]);
else in;
}
if (mmp[i+][j]){
s=s^q*(<<bit[j])^q*(<<bit[j-]);
sum+=mp[i+][j]; in;
}
}else if(p && !q){
if (mmp[i+][j]) hash_in(s,sum+mp[i+][j]);
if (mmp[i][j+]){
s=s^p*(<<bit[j])^p*(<<bit[j-]);
if (!d)sum+=mp[i][j+];
in;
}
}else if(p+q==){
int nd=;
F(u,j+,m){
int w=(s>>bit[u])&;
if (w==) nd++;
if (w==) nd--;
if (!nd){ s-=<<bit[u]; break; }
}
s=s^(<<bit[j-])^(<<bit[j]),in;
}else if(p+q==){
int nd=;
D(u,j-,){
int w=(s>>bit[u])&;
if (w==) nd++;
if (w==) nd--;
if (!nd){ s+=<<bit[u]; break; }
}
s=s^(<<bit[j-]<<)^(<<bit[j]<<),in;
}else if(p== && q==){
s=s^(<<bit[j-]<<)^(<<bit[j]),in;
}else if(p== && q==) continue;
}
}
F(j,,tot[k]) state[k][j]<<=;
}
F(i,,tot[k]) ans=max(ans,dp[k][i]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("3377.in","r",stdin);
// freopen("output.txt","w",stdout);
#endif
F(i,,) bit[i]=i<<;
int T=;
while(scanf("%d%d",&n,&m)!=EOF){
init();
work();
printf("Case %d: %lld\n",++T,ans);
}
return ;
}

【HDOJ】【3377】Plan的更多相关文章

  1. 【HDOJ图论题集】【转】

    =============================以下是最小生成树+并查集====================================== [HDU] How Many Table ...

  2. 【集训笔记】博弈论相关知识【HDOJ 1850【HDOJ2147

    以下资料来自:http://blog.csdn.net/Dinosoft/article/details/6795700 http://qianmacao.blog.163.com/blog/stat ...

  3. 【HDOJ 5379】 Mahjong tree

    [HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共同拥有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根 ...

  4. HDOJ 1238 Substrings 【最长公共子串】

    HDOJ 1238 Substrings [最长公共子串] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...

  5. HDOJ 1423 Greatest Common Increasing Subsequence 【DP】【最长公共上升子序列】

    HDOJ 1423 Greatest Common Increasing Subsequence [DP][最长公共上升子序列] Time Limit: 2000/1000 MS (Java/Othe ...

  6. HDOJ 1501 Zipper 【DP】【DFS+剪枝】

    HDOJ 1501 Zipper [DP][DFS+剪枝] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...

  7. 【HDOJ 2089】不要62

    [HDOJ 2089]不要62 第一个数位dp的题 做的老困难了...只是好歹是做出来了 迈出了第一步.. 对大牛来说这样的题都是小case ps:新上一个记忆化方法 一些绕弯的题里用dfs好想些 代 ...

  8. 【HDOJ 5371】 Hotaru&#39;s problem

    [HDOJ 5371] Hotaru's problem Manacher算法+穷举/set Manacher算法一好文:http://blog.csdn.net/yzl_rex/article/de ...

  9. 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)

    pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...

  10. 【HDOJ 5399】Too Simple

    pid=5399">[HDOJ 5399]Too Simple 函数映射问题 给出m函数 里面有0~m个函数未知(-1) 问要求最后1~n分别相应仍映射1~n 有几种函数写法(已给定的 ...

随机推荐

  1. 8-3 Bits Equalizer uva12545

    题意: 给出字符串s包含'0' '1' '?'; 再给出字符串t只包含01: 现在我们可以对S做三个操作:把0变成1,把?变成0或1,任意两个位置交换: 问最少操作几次s == t: 贪心 默认除去那 ...

  2. 集群运维ansible

    ssh免密登录 集群运维 生成秘钥,一路enter cd ~/.ssh/ ssh-keygen -t rsa 讲id_rsa.pub文件追加到授权的key文件中 cat ~/.ssh/id_rsa.p ...

  3. Spring技术内幕:设计理念和整体架构概述(转)

    程序员都很崇拜技术大神,很大一部分是因为他们发现和解决问题的能力,特别是线上出现紧急问题时,总是能够快速定位和解决. 一方面,他们有深厚的技术基础,对应用的技术知其所以然,另一方面,在采坑的过程中不断 ...

  4. 新一代数据库TiDB在美团的实践

    1. 背景和现状 近几年,基于MySQL构建的传统关系型数据库服务,已经很难支撑美团业务的爆发式增长,这就促使我们去探索更合理的数据存储方案和实践新的运维方式.而随着分布式数据库大放异彩,美团DBA团 ...

  5. python opencv3 检测人

    git:https://github.com/linyi0604/Computer-Vision # coding:utf-8 import cv2 # 检测i方框 包含o方框 def is_insi ...

  6. 【递推】Codeforces Round #483 (Div. 2) [Thanks, Botan Investments and Victor Shaburov!] D. XOR-pyramid

    题意:定义,对于a数组的一个子区间[l,r],f[l,r]定义为对该子区间执行f操作的值.显然,有f[l,r]=f[l,r-1] xor f[l+1,r].又定义ans[l,r]为满足l<=i& ...

  7. python开发_csv(Comma Separated Values)_逗号分隔值_常用导入导出格式_完整版_博主推荐

    ## 最近出了一趟差,是从20号去的,今天回来...# 就把最近学习的python内容给大家分享一下...#''' 在python中,CSV(Comma Separated Values),从字面上面 ...

  8. HDU 5694 BD String 迭代

    BD String 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5694 Description Problem Description 众所周知, ...

  9. nlogn 求最长上升子序列 LIS

    最近在做单调队列,发现了最长上升子序列O(nlogn)的求法也有利用单调队列的思想. 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]& ...

  10. python循环与判断

    学习一门新的语言最重要的就是练习. 一.脚本需求: 编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定 二.脚本流程图: 写代码之前画个流程图总是好的,可以让你理清思路,避免写着写着 ...