题目大意:

从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了

这里有个思路是转化成熟悉的回路问题

在上方和右方最外围定义一圈权值为0 , 那么我们相当于从定义以后的左上角开始经过所有外围点形成的回路,那么去掉最外围的0,剩下的就是(1,1)-》(n,n)的权值和了

但是这里最外围的点的插头具有特殊性,每次到最外围的点,你左和上有且仅有一个插头,而且出去的方向必然是下一个最外围的点

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
#define ll long long
const int HASH = ;
const int STATE = ;
const int MAXD = ;
int n , m;
int code[MAXD] , mp[MAXD][MAXD];
bool flag[MAXD][MAXD];//标记位,标记当前点能否作为最终点
ll ans = ;
int w[MAXD][MAXD];
struct HASHMAP{
int head[HASH] , next[STATE] , state[STATE] , size;
ll f[STATE]; void init(){
size = ;
memset(head , - , sizeof(head));
} void push_in(int st , ll sum){
int h = st%HASH;
for(int i = head[h] ; ~i ; i=next[i]){
if(st == state[i]){
f[i]=max(f[i] , sum); //这题目为求最大值
return ;
}
}
f[size]=sum;
state[size] = st;
next[size] = head[h];
head[h] = size++;
}
}hashmap[]; int num = ;//记录共有的插头数量
void decode(int *code , int m , int st)
{
num = ;
for(int i=m ; i>= ; i--){
code[i] = st&;
st>>=;
if(code[i]) num++;
}
} int encode(int *code , int m)
{
int st=;
for(int i= ; i<=m ; i++){
st<<=;
st |= code[i];
}
return st;
} void shift(int *code , int m) //换行,可理解为将最右侧轮廓线换到了下一行的最左侧
{
for(int i=m ; i>= ; i--) code[i] = code[i-];
code[] = ;
} void dpblank(int i , int j , int cur)
{
int k , left , up;
for(k= ; k<hashmap[cur].size ; k++){
decode(code , m , hashmap[cur].state[k]);
left = code[j-];
up = code[j];
if(!left && !up){
if(mp[i][j]==) continue;
if(mp[i][j]==){
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
}
if(mp[i][j+] && mp[i+][j]){
code[j-] = , code[j] = ;
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
}
else if(!left && up){
if(mp[i][j]== && (up!=)) continue;
else if(mp[i][j]==){
if(mp[i][j+]==) hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
else{
code[j-] = up , code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
continue;
}
if(mp[i][j+]) hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
if(mp[i+][j]){
code[j-] = up , code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
}
else if(left && !up){
if(mp[i][j]== && (left!=)) continue;
else if(mp[i][j]==){
if(mp[i][j+]==){
code[j-] = , code[j] = left;
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}else{
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
continue;
}
if(mp[i+][j]){
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
if(mp[i][j+]){
code[j-] = , code[j] = left;
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
}
else if(mp[i][j]==) continue;
else if(left== && up == ){
int cnt = ;
for(int v=j+ ; v<=m ; v++){
if(code[v]==)cnt++;
if(code[v]==)cnt--;
if(!cnt){
code[v]=;
break;
}
}
code[j-] = code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
else if(left == && up == ){
int cnt=;
for(int v=j- ; v>= ; v--){
if(code[v]==)cnt++;
if(code[v]==)cnt--;
if(!cnt){
code[v]=;
break;
}
}
code[j-] = code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
else if(left== && up==){
if(i==n && j==m) ans=max(ans,hashmap[cur].f[k]+w[i][j]);
}
else{
code[j-]=code[j]=;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
}
}
} void init()
{
for(int i= ; i<=m+ ; i++) mp[][i]= , w[][i] = ;
for(int i= ; i<=n+ ; i++){
for(int j= ; j<=m ; j++)
scanf("%d" , &w[i][j]) , mp[i][j]=;
w[i][m+] = , mp[i][m+] = ;
mp[i][m+] = mp[n+][i]=;
} n++ , m++;
mp[][] = mp[n][m] = ;
/*for(int i=1 ; i<=n ; i++){
for(int j=1 ;j <=m ; j++){
cout<<mp[i][j]<<" ";
}
cout<<endl;
}*/
} ll solve()
{
ans = -1e9;
int cur = ;
hashmap[cur].init();
hashmap[cur].push_in( , );
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++){
hashmap[cur^].init();
dpblank(i , j , cur);
cur ^= ;
/* cout<<"test: "<<i<<" "<<j<<endl;
for(int k=0 ; k<hashmap[cur].size ; k++)
cout<<hashmap[cur].f[k]<<endl;*/ }
}
// for(int i=0 ; i<hashmap[cur].size ; i++)
return ans;
} int main()
{
// freopen("in.txt" , "r" , stdin);
int cas = ;
while(~scanf("%d%d" , &n , &m))
{
init();
printf("Case %d: ",++cas);
if(n== && m==){
printf("%d\n" , w[][]);
continue;
}
printf("%I64d\n" , solve());
}
return ;
}

HDU 3377 插头dp的更多相关文章

  1. hdu 1693 插头dp入门

    hdu1693 Eat the Trees 题意 在\(n*m\)的矩阵中,有些格子有树,没有树的格子不能到达,找一条或多条回路,吃完所有的树,求有多少种方法. 解法 这是一道插头dp的入门题,只需要 ...

  2. HDU 1693 插头dp入门详解

    放题目链接   https://vjudge.net/problem/22021/origin 给出一个n*m的01矩阵,1可走0不可通过,要求走过的路可以形成一个环且可以有多个环出现,问有多少不同的 ...

  3. HDU 3377 Plan (插头DP,变形)

    题意:有一个n*m的矩阵,每个格子中有一个值(可能负值),要从左上角走到右下角,求路径的最大花费. 思路: 除了起点和终点外,其他的点可以走,也可以不走. (2)我用的是括号表示法,所以起始状态为') ...

  4. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

  5. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

  6. hdu 1693 Eat the Trees——插头DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...

  7. HDU 4949 Light(插头dp、位运算)

    比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...

  8. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

  9. HDU 1693 Eat the Trees(插头DP)

    题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...

随机推荐

  1. iOS开发之Xcode 如何使用API帮助

    内容转载自<iOS开发指南 2.6.2 如何使用API帮助> 对于一个初学者来说,学会在Xcode中使用API帮助文档是非常重要的.下面我们通过一个例子来介绍API帮助文档的用法.在编写H ...

  2. mysql ERROR 1044 (42000): Access denied for user ''@'localhost' to database

    新安装的mysql密码是空的. ./mysql -u root -p use mysql SELECT `Host`,`User` FROM user; UPDATE user SET `Host` ...

  3. hibernate的注解属性mappedBy详解

    mappedBy: 1>只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性: 2>mappedBy标签一定是定义在被拥 ...

  4. 面向对象的static关键字(类中的static关键字)

    转自:http://blog.csdn.net/xiayefanxing/article/details/7382192 http://www.cnblogs.com/SelaSelah/archiv ...

  5. 牛客网 --java问答题

    http://www.nowcoder.com/ 主要是自己什么都不怎么会.在这里可以学习很多的! 第一天看题自己回答,第二天看牛客网的答案! 1 什么是Java虚拟机?为什么Java被称作是“平台无 ...

  6. js中正则表达式 书写方法

    function test(){    var text="index.aspx?test=1&ww=2&www=3";            var   re = ...

  7. CSS3的颜色透明度 ajax请求时loading

    1.background-color:rgba(0,0,0,0.65)         这行代码让覆盖层变黑色,且有0.6的透明度 正常情况下遮盖层会把透明度遗传给弹出框(它的子元素),但是利用CSS ...

  8. 【bzoj1018】堵塞的交通

    [bzoj1018]堵塞的交通 题意 一个\(2*n\)的格子,相邻格子之间有一条道路.初始时道路是不通的. \(C\)个操作,每个操作为三种中的一种:(1)某条道路连起来:(2)某条道路断开:(3) ...

  9. 2.2 利用项目模板创建ASP.NET MVC项目

    1.启动VS2012,点击“文件|新建|项目”. 2.在新建项目的窗口中,选择ASP.NET MVC 4应用程序. 3.在新ASP.NET MVC 4项目窗口中的“选择模板”列表中选择“基本”模板,在 ...

  10. ubuntu 64位android项目报错的解决方案,打开64位 Ubuntu 的32位支持功能

    ubuntu的64位下的android环境,说实话,还真得费点精力了,解决一个问题,又出来一个新问题. 小编昨天刚好不容易将android的环境搭建好了,这不,刚建了个项目,直接就报错,下面是罗列出的 ...