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. 接口json数据与数据库数据循环比对校验

    创建测试计划,加载数据库驱动: 线程组: csv配置元件: 注:Filename用的是相对路径,csv文件要与jmeter脚本文件在同一目录 JDBC连接配置: jdbc请求: 用户定义的变量: ht ...

  2. java8 新特性入门 stream/lambda

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...

  3. linux使用freetds 连接连远程服务器sqlservser2012

    1.下载:freetds-patched.tar.gz  http://www.freetds.org/software.html http://www.freetds.org/userguide/c ...

  4. SQL Server 服务器主体拥有一个或多个端点无法删除;错误15141

    一.问题描述 当前数据库实例之前已经加入过一个域环境同时也是alwayson集群的一个副本,现在已经退出了以前的域加入一个新域,而且配置的数据库启动服务的域用户和密码和之前的一样.重新使用之前已经存在 ...

  5. webpack 3.X学习之多页面打包

    简介 我们开发不可能只写一个页面,每次都要写很多页面,这时为了开发效率,我们使用前端自动化工具webpack,那么webpack是如何打包页面的呢?又是如何打包多页面的呢? 单页面打包 我们知道要打包 ...

  6. JAVA Socket编程(一)之UDP通信

    常见的通讯协议有udp和tcp. --将数据及源.目的封装在数据包中,不需要建立连接: --每个数据包的大小限制在64k以内: --因无连接,是不可靠协议: --不需要建立连接,所以传输速度快,但是容 ...

  7. intelij Android 搭建 java 项目

    1.打开ide创建页面,点击创建项目 2.选择Android,发现下面有一段红字,解释很清楚,由于第一使用为设置Android的开发环境sdk,去设置一下就好,点击取消回到上一界面 3 配置 4.当然 ...

  8. Git安装和使用(谨记)

    刚开始用git的小白适用,,转自http://www.cnblogs.com/qijunjun/p/7137207.html 实际项目开发中,我们经常会用一些版本控制器来托管自己的代码,今天就来总结下 ...

  9. Equilibrium point

    Given an array A your task is to tell at which position the equilibrium first occurs in the array. E ...

  10. Docker(六):Docker网络配置进阶

    1.Docker集群网络配置之Weave Weave是Github上一个比较热门的Docker容器网络方案,具有非常良好的易用性且功能强大.仓库地址:https://github.com/weavew ...