博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva 10913 Walking on a Grid
阅读量:6403 次
发布时间:2019-06-23

本文共 2790 字,大约阅读时间需要 9 分钟。

题意给出一个n*n的方阵,从(1,1)出发到(n,n)目的是找出一条路径,这条路径上的点的值为负数的个数要小于等于k,在满足这个条件之下,使路径之和最大,如果无法找到这样的路径(即负数的个数一定大于k)则输出impossible

定义状态为四维,f[i][j][k][v],表示从v方向来到当前的点(i,j),已经用掉的负数的个数是k,所能得到的最大值。V=0表示从上面递归而来的,接下来可以向下,左,右递归。V=1表示从左边递归而来,接下来可以向下,右递归。V=2表示从右边递归而来,接下来可以向下,左递归。

然后就是注意初始化的问题和一些值要记得赋初值的问题,整个记忆所搜索的思路还是比较容易理解的

 

 

#include 
#include
#define MAXN 80#define MAXK 10#define INF -198873434long long f[MAXN][MAXN][MAXK][3];bool visit[MAXN][MAXN][MAXK][3];int a[MAXN][MAXN];int N,K;void input(){ int i,j; for(i=1; i<=N; i++) for(j=1; j<=N; j++) scanf("%d",&a[i][j]);}long long max(int t1 , int t2 , int t3){ if(t1>=t2 && t1>=t3) return t1; else if(t2>=t1 && t2>=t3) return t2; else return t3;}long long DP(int i , int j ,int k ,int v){ int kk; long long t1,t2,t3,m; if(visit[i][j][k][v]) return f[i][j][k][v]; visit[i][j][k][v]=1; if(k==K && a[i][j]<0) return f[i][j][k][v]=INF; if(i==N && j==N) return f[i][j][k][v]=a[i][j];// f[i][j][k][v]=INF; if(a[i][j]<0) kk=k+1; else kk=k; if(v==0) //从上而来 { t1=t2=t3=INF; //要记得赋初值因为有递归不能进行这三个变量不一定能得到一个返回值 if(i<=N-1) t1=DP(i+1,j,kk,0); //向下递归,对于下一层而言是从上而来,只能向下左右递归 if(j>=2) t2=DP(i,j-1,kk,2); //向左递归,对于下一层而言是从右而来,只能向下左递归 if(j<=N-1) t3=DP(i,j+1,kk,1); //向右递归,对于下一层而言是从左而来,只能向下右递归 m=max(t1,t2,t3); if(m!=INF && m+a[i][j]>f[i][j][k][v]) f[i][j][k][v]=m+a[i][j]; } else if(v==1) //从左而来 { t1=t2=t3=INF; //要记得赋初值因为有递归不能进行这三个变量不一定能得到一个返回值 if(i<=N-1) t1=DP(i+1,j,kk,0); if(j<=N-1) t2=DP(i,j+1,kk,1); m=max(t1,t2,t3); if(m!=INF && m+a[i][j]>f[i][j][k][v]) f[i][j][k][v]=m+a[i][j]; } else //从右而来 { t1=t2=t3=INF; //要记得赋初值因为有递归不能进行这三个变量不一定能得到一个返回值 if(i<=N-1) t1=DP(i+1,j,kk,0); if(j>=2) t2=DP(i,j-1,kk,2); m=max(t1,t2,t3); if(m!=INF && m+a[i][j]>f[i][j][k][v]) f[i][j][k][v]=m+a[i][j]; } return f[i][j][k][v];}void solve(int T){ int i,j,k,v; long long ans; for(i=1; i<=N; i++) for(j=1; j<=N; j++) for(k=0; k<=K; k++) for(v=0; v<=2; v++) f[i][j][k][v]=INF; memset(visit, 0, sizeof(visit)); ans=DP(1,1,0,0); if(ans!=INF) printf("Case %d: %lld\n",T,ans); else printf("Case %d: impossible\n",T);}int main(){ int T=0; while(scanf("%d%d",&N,&K)!=EOF) { if(!N && !K) break; T++; input(); solve(T); } return 0;}

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/scau20110726/archive/2012/09/28/2707010.html

你可能感兴趣的文章
(五)Docker镜像管理3之上传镜像
查看>>
elasticsearch 多次聚合
查看>>
SUSE11开启Xmanager
查看>>
Scala 语言学习之泛型(7)
查看>>
centos 7 网卡命名
查看>>
python--字典类型
查看>>
Powershell 批量重命名
查看>>
zabbix proxy搭建及其排错
查看>>
如何利用报表工具FineReport实现报表列的动态展示
查看>>
IC卡制作常识概述
查看>>
centos EMQTTD 集群安装配置与测试验证
查看>>
MYSQL常用的架构和优化及常用的配置详解及MySQL数据库主从同步延迟原理
查看>>
Renewing a self-signed certificate in SBS 2003
查看>>
分布式文件系统之配置DFS复制
查看>>
【Maclean技术分享】开Oracle调优鹰眼,深入理解AWR性能报告 第二讲
查看>>
linux的启动过程详解
查看>>
MySQL多线程备份工具:mydumper
查看>>
如何配置用于运行数据库的虚拟机。
查看>>
SVN笔记
查看>>
border 外边框
查看>>