Problem Description
One day, Resty comes to an incredible world to seek Eve -- The origin of life. Lilith, the sister of Eve, comes with him. Although Resty wants to find Eve as soon as possible, Lilith likes to play games so much that you can't make her make any move if you don't play with her.

Now they
comes to the magical world and Lilish ask Resty to play with her.

The
game is following :
Now the world is divided into a m * n grids by Lilith,
and Lilith gives each grid a score.
So we can use a matrix to describe
it.
You should come from cell(0, 0) to cell(m-1, n-1) (Up-Left to Down-Right)
and try to colloct as more score as possible.
According to Lilish's rule, you
can't arrive at each cell more than once.

Resty knows that Lilish will be
easy to find the max score, and he doesn't want to lose the game.
So he want
to find the game plan to reach the max score.

Your task is to calculate
the max score that Lilish will find, the map is so small so it shouldn't be
difficult for you, right?

 
Input
The input consists of more than one
testdata.
Process to the END OF DATA.
For each test data :
the first
live give m and n. (1<=m<=8, 1<=n<=9)
following m lines, each
contain n number to give you the m*n matrix.
each number in the matrix is
between -2000 and 2000
 
Output
Output Format is "Case ID: ANS" one line for each
data
Don't print any empty line to the output
 
Sample Input
2 2
1 2
3 1
3 3
0 -20 100
1 -20 -20
1 1 1
 
Sample Output
Case 1: 5
Case 2: 61
 
插头dp
左上角走到右下角,不得重复经过格子,也可以不经过,求最大分数。
两种方法,第一是上下加两行,加两列,加障碍,使题目变成简单的回路,而不是单路。
第二在起点终点都加一个单插头处理,其他地方也应相应微调,不过我好像调得不好,一直WA……233,不过本机测了数百组数据都是对哒,所以不管了……
/*第一种方法*/
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mn=;
int i;
struct na{
int x,z;
na(int xx,int zz):x(xx),z(zz){}
};
int n,m,x,y,z,a[],k,en,u=,p1,p2;
bool map[][];
int f[][mn+],ans;
int v[][mn+];
int re[][];
queue <na> q;
inline int gx(int x,int q1,int q2){k=;for (register int i=m+;i;i--) k=k*+(i==x?q1:(i==x+?q2:a[i]));return k;}
inline void up(int x,int z,int lj,bool la){
if (la) lj+=re[x/m+][x%m+];
x++;
k=x%;
if (v[k][z]!=x) v[k][z]=x,f[k][z]=-1e9,q.push(na(x,z));
f[k][z]=max(f[k][z],lj);
}
int main(){
//freopen("a.in","r",stdin);
register int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
u++;
printf("Case %d: ",u);
ans=-1e9;
memset(map,,sizeof(map));memset(v,,sizeof(v));memset(re,,sizeof(re));memset(f,,sizeof(f));
for (i=;i<=m;i++)
for (j=;j<=n;j++)
map[i][j+]=;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
scanf("%d",&re[i+][j]);
n+=;
m+=;
en=n*m-;
for (i=;i<=m;i++) map[i][]=map[i][n]=;
for (i=;i<=n;i++) map[m][i]=;
map[][]=;map[m-][n-]=;
if (n==&&m==){
printf("%d\n",re[][]);
continue;
}
f[][]=;v[][]=;
q.push(na(,));
while(!q.empty()){
na no=q.front();q.pop();
int an=f[no.x%][no.z];
if(no.x%m==) no.z*=;
x=no.x%m+;y=no.x/m+;
for (i=;i<=m+;i++) a[i]=;
for (i=,j=no.z;j;i++,j/=) a[i]=j%;
if (!map[x][y])up(no.x,gx(x,,),an,);else
if (a[x]==&&a[x+]==){
if (no.x==en) ans=max(ans,an);
}else if (a[x]==&&a[x+]==) up(no.x,gx(x,,),an,);else
if (a[x]==&&a[x+]==){
if (no.x!=en&&no.x!=) up(no.x,gx(x,,),an,);
if (map[x][y+]&&map[x+][y]) up(no.x,gx(x,,),an,);
}else if (a[x]==){
if (map[x+][y]) up(no.x,gx(x,,a[x+]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x+],),an,);
}else if (a[x+]==){
if (map[x+][y]) up(no.x,gx(x,,a[x]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x],),an,);
}else if (a[x]==a[x+]){
p1=p2=;
if (a[x]==)
for (j=,i=x+;i<=m;i++){
if (a[i]==) j--;
if (a[i]==) j++;
if (j>&&!p1) p1=i,j--;
if (j>&&p1){p2=i;break;}
}else
for (j=,i=x-;i;i--){
if (a[i]==) j++;
if (a[i]==) j--;
if (j>&&!p2) p2=i,j--;
if (j>&&p2){p1=i;break;}
}
a[p1]=;a[p2]=;up(no.x,gx(x,,),an,);
}
}
printf("%d\n",ans);
}
}
/*第二种方法*/
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int i;
struct na{
int x,z;
na(int xx,int zz):x(xx),z(zz){}
};
int n,m,x,y,z,a[],k,en,u=,p1,p2;
bool map[][];
int f[][],ans;
int v[][];
int re[][];
queue <na> q;
inline int gx(int x,int q1,int q2){k=;for (register int i=m+;i;i--) k=k*+(i==x?q1:(i==x+?q2:a[i]));return k;}
inline void up(int x,int z,int lj,bool la){
if (la) lj+=re[x/m+][x%m+];
x++;
k=x%;
if (v[k][z]!=x) v[k][z]=x,f[k][z]=lj,q.push(na(x,z));
if (lj>f[k][z]) f[k][z]=lj;
}
int main(){
register int i,j;
while(scanf("%d%d",&n,&m)!=EOF){
u++;
ans=;
memset(map,,sizeof(map));memset(v,,sizeof(v));memset(f,,sizeof(f));
en=n*m-;
for (i=;i<=m;i++)
for (j=;j<=n;j++)
map[i][j]=;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
scanf("%d",&re[i][j]);
if (n==&&m==){
printf("Case %d: %d\n",u,re[][]);
continue;
}
f[][]=;
v[][]=;
q.push(na(,));
while(!q.empty()){
na no=q.front();q.pop();
int an=f[no.x%][no.z];
if (no.x%m==) no.z*=;
x=no.x%m+;y=no.x/m+;
for (i=;i<=m+;i++) a[i]=;
for (i=,j=no.z;j;i++,j/=) a[i]=j%;
if (no.x==en){
k=;
for (i=;i<=m+;i++) k+=a[i]!=;
if (k==&&(a[m]==||a[m+]==)&&an+re[n][m]>ans) ans=an+re[n][m];
continue;
}
if (a[x]==&&a[x+]==){
up(no.x,gx(x,,),an,);
}else if (a[x]==&&a[x+]==){
up(no.x,gx(x,,),an,);
if (map[x][y+]&&map[x+][y])
up(no.x,gx(x,,),an,);
}else if (a[x]==){
if (map[x+][y]) up(no.x,gx(x,,a[x+]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x+],),an,);
}else if (a[x+]==){
if (map[x+][y]) up(no.x,gx(x,,a[x]),an,);
if (map[x][y+]) up(no.x,gx(x,a[x],),an,);
}else if (a[x]==&&a[x+]==){
p1=p2=;
for (j=,i=x+;i<=m+;i++){
if (a[i]==) j--;
if (a[i]==) j++;
if (j>&&!p1) p1=i,j--;
if (j>&&p1){p2=i;break;}
}
a[p1]=;a[p2]=;
up(no.x,gx(x,,),an,);
}else if (a[x]==&&a[x+]==){
p1=p2=;
for (j=,i=x-;i;i--){
if (a[i]==) j++;
if (a[i]==) j--;
if (j>&&!p2) p2=i,j--;
if (j>&&p2){p1=i;break;}
}
a[p1]=;a[p2]=;up(no.x,gx(x,,),an,);
}
}
printf("Case %d: %d\n",u,ans);
}
}

HDU 3377 Plan的更多相关文章

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

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

  2. HDU 3377 插头dp

    题目大意: 从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了 这里有个思路是转化成熟悉的回路问题 在上方和右方最外围定义一圈权值为0 , ...

  3. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  4. 插头dp练习

    最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...

  5. HDU 3080 The plan of city rebuild(prim和kruskal)

    The plan of city rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  6. HDU 3757 Evacuation Plan DP

    跟 UVa 1474 - Evacuation Plan 一个题,但是在杭电上能交过,在UVa上交不过……不知道哪里有问题…… 将施工队位置和避难所位置排序. dp[i][j] 代表前 i 个避难所收 ...

  7. hdu 5540 Secrete Master Plan(水)

    Problem Description Master Mind KongMing gave Fei Zhang a secrete master plan stashed × matrix, but ...

  8. hdu 5290 Bombing plan

    http://acm.hdu.edu.cn/showproblem.php?pid=5290 题意: 一棵树,每个点有一个权值wi,选择点i即可破坏所有距离点i<=wi的点,问破坏所有点 最少需 ...

  9. 【HDOJ】【3377】Plan

    插头DP sigh……其实思路很简单的= =就多加一种转移:从(0,0)->(0,0),也就是不走这个格子…… 初始状态就是第一格有一个左插头= =结束状态可以让(n,m)这个位置可以走到(n+ ...

随机推荐

  1. 日期函数ADD_MONTHS,MONTHS_BETWEEN,LAST_DAY,NEXT_DAY

  2. ES6异步操作Thunk、co和async

    使用Thunk函数对Generator函数进行流程管理,首先什么是Thunk函数?我们应该先说下参数的求值策略,编译器的求值策略一个是"传值调用"另一个是"传名调用&qu ...

  3. GitLab配置ssh key

    一.背景 当前很多公司都选择git作为代码版本控制工具,然后自己公司搭建私有的gitlab来管理代码,我们在clone代码的时候可以选择http协议,当然我们亦可以选择ssh协议来拉取代码.但是网上很 ...

  4. 快速自检电脑是否被黑客入侵过(Linux版)

    之前写了一篇快速自检电脑是否被黑客入侵过(Windows版), 这次就来写写Linux版本的. 前言 严谨地说, Linux只是一个内核, GNU Linux才算完整的操作系统, 但在本文里还是用通俗 ...

  5. xamarin android制作圆角边框

    xamarin android制作圆角边框 效果图如下: 关键代码: drawable文件夹新建shape_corner_down.xml <?xml version="1.0&quo ...

  6. lesson - 6 课程笔记

    一.df  作用:  显示磁盘分区上的可使用的磁盘空间, 默认显示单位为kb . 可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间的等信息. 选项: -a :包含全部的文件系统 -h :以 ...

  7. WINDOWS下运行ORACLE SQLPLUS时报错的一次记录

    环境变量配置无误后,在sys用户 在pl/sql上登录时候报以下错误 ORA-01034: ORACLE not available进程 ID: 0会话 ID: 0 序列号: 0 然后运行控制台,有以 ...

  8. spring boot 遇到 supported setting property http://xml.org/sax/properties/lexical-handler

    解决链接:http://apache-fop.1065347.n5.nabble.com/org-xml-sax-SAXNotSupportedException-thrown-by-FOP-td11 ...

  9. react看这篇就够了(react+webpack+redux+reactRouter+sass)

    本帖将对一下内容进行分享: 1.webpack环境搭建: 2.如何使用react-router: 3.引入sass预编译: 4.react 性能优化方案: 5.redux结合react使用: 6.fe ...

  10. h5拖拽上传图片

    h5实现拖拽上传图片 本文将为大家介绍如何通过js实现拖拽上传图片. 首先我们要禁用调浏览器默认的拖拽事件: window.onload = function(){ //拖离 document.add ...