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

本文共 2706 字,大约阅读时间需要 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;}

 

 

 

 

 

 

 

转载地址:http://vhzhl.baihongyu.com/

你可能感兴趣的文章
WDS和DHCP配置说明
查看>>
深入理解计算机系统6——存储器层次结构
查看>>
【WPF新手快速入门系列】2.绑定
查看>>
MJRefresh tableview基本刷新的封装
查看>>
OpenStack视图
查看>>
有效用例模式阅读笔记一
查看>>
网络爬虫(一)
查看>>
查看Win7系统的cookies
查看>>
mailto调用本地默认客户端发邮件
查看>>
Windows中读写ini文件
查看>>
SQL Server 数据导入
查看>>
cmakelists.txt中配置openg环境出现: undefined reference to symbol 'glLightfv'
查看>>
Android五大布局对象--FrameLayout,LinearLayout,AbsoluteLayout,RelativeLayout,TableLayout
查看>>
JavaScript基础-2
查看>>
python实训第四天
查看>>
5-4-3原则
查看>>
html图像入门
查看>>
C# Mongo Client 2.4.2创建索引
查看>>
我的第四个网页制作:列表标签
查看>>
【python进阶】详解元类及其应用2
查看>>