HDU 3377 Plan
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?
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
data
Don't print any empty line to the output
两种方法,第一是上下加两行,加两列,加障碍,使题目变成简单的回路,而不是单路。
/*第一种方法*/
#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的更多相关文章
- HDU 3377 Plan (插头DP,变形)
题意:有一个n*m的矩阵,每个格子中有一个值(可能负值),要从左上角走到右下角,求路径的最大花费. 思路: 除了起点和终点外,其他的点可以走,也可以不走. (2)我用的是括号表示法,所以起始状态为') ...
- HDU 3377 插头dp
题目大意: 从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了 这里有个思路是转化成熟悉的回路问题 在上方和右方最外围定义一圈权值为0 , ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- 插头dp练习
最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...
- 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 ...
- HDU 3757 Evacuation Plan DP
跟 UVa 1474 - Evacuation Plan 一个题,但是在杭电上能交过,在UVa上交不过……不知道哪里有问题…… 将施工队位置和避难所位置排序. dp[i][j] 代表前 i 个避难所收 ...
- hdu 5540 Secrete Master Plan(水)
Problem Description Master Mind KongMing gave Fei Zhang a secrete master plan stashed × matrix, but ...
- hdu 5290 Bombing plan
http://acm.hdu.edu.cn/showproblem.php?pid=5290 题意: 一棵树,每个点有一个权值wi,选择点i即可破坏所有距离点i<=wi的点,问破坏所有点 最少需 ...
- 【HDOJ】【3377】Plan
插头DP sigh……其实思路很简单的= =就多加一种转移:从(0,0)->(0,0),也就是不走这个格子…… 初始状态就是第一格有一个左插头= =结束状态可以让(n,m)这个位置可以走到(n+ ...
随机推荐
- (转载)Eclipse将引用了第三方jar包的Java项目打包成可执行jar的两种方法
转载自:http://www.cnblogs.com/lanxuezaipiao/p/3291641.html 方案一:用Eclipse自带的Export功能 步骤1:准备主清单文件 "MA ...
- 数据库入门(以MySQL为例)
一.数据库中的概念 1.数据库是用户存放数据.访问数据.操作数据的存储仓库,用户的各种数据被有组织地存放在数据库中.可以随时被有权限的用户查询.统计.添加.删除.和修改.可以说,数据库是长期存储在计算 ...
- php trim源码分析
本文同时发表于https://github.com/zhangyachen/zhangyachen.github.io/issues/9 核心代码如下: /* {{{ php_trim() * mod ...
- 724. Find Pivot Index
Given an array of integers nums, write a method that returns the "pivot" index of this arr ...
- redis中使用 check-and-set 操作实现乐观锁
WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为. 被 WATCH 的键会被监视,并会发觉这些键是否被改动过了. 如果有至少一个被监视的键在 EXEC 执行之前 ...
- lesson - 4 Linux目录文件管理
内容概要:1. 和目录相关的几个命令mkdir 关注-p选项 rmdir 同样也有一个-p选项rm -r -f 两个常用选项cp -r 针对目录, 有时我们使用/bin/cpmv 重命名或者移动, 有 ...
- [编织消息框架][netty源码分析]1分析切入点
在分析源码之前有几个疑问 1.BOSS线程如何转交给handle(业务)线程2.职业链在那个阶段执行3.socket accept 后转给上层对象是谁4.netty控流算法 另外要了解netty的对象 ...
- springBoot系列教程05:fastjson的集成、配置及使用
springBoot自带的json用着不太习惯,已习惯了fastJSON,下面介绍下fastjson的配置 1. pom引入 <dependency> <groupId>com ...
- 第一个Vue插件从封装到发布
前言 这是我封装的第一个Vue插件,实现的功能是滑动选择省市区,虽然只是一个简单的插件,但还是挺开心的,记录一下步骤. 插件地址:https://github.com/leichangchun/vue ...
- SQL基础学习_06_集合运算和联结
集合运算 1. 并集:UNION 例: SELECT shohin_id, shohin_mei FROM Shohin UNION SELECT shohin_id ...