LightOJ-1071-dp,dfs

11 篇文章 0 订阅

题目大意:给定一张网格图,起始点为(1,1),终点为(n,m),需要来回走两次,但是只允许起点终点是一样的,其余都不可以,问最多可以帮助多少个人;

题目解析:我们可以转化一下,转化成两个人,一个人从(1,2)出发走向(n-1,m),另一个人从(2,1)出发,走向(n,m-1);假设他们两个人在途中某一点(x,y)相遇了,那么他们两个到达这个点所经过的时间一定相同,所以要保证两个人始终不会相遇,只需保证在每个时间点他们两个人都不相遇即可;定义dp[i][j][k]表示在i这个时间点,第一个人的x坐标为j,第二个人的x坐标为k,到达目标位置能获取的最大权值,dp的时候记忆化搜索就ok了;

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int dp[201][101][101],graph[107][107],n,m;
const int inf=0x3fffffff;
int dfs(int pos,int x1,int x2)
{
	if(dp[pos][x1][x2]!=-1)	return dp[pos][x1][x2];
	int y1=pos-x1,y2=pos-x2;
	if(x1>n||y1>m||x2>n||y2>m||(x1==x2&&y1==y2))	return -1;
	int ans=graph[x1][y1]+graph[x2][y2];
	if(x1==n&&y1==m-1&&x2==n-1&&y2==m)
	{
		return ans;
	}		
	int temp=0;
	if(dfs(pos+1,x1,x2)!=-1)
		temp=max(temp,dfs(pos+1,x1,x2));
	if(dfs(pos+1,x1+1,x2)!=-1)
		temp=max(temp,dfs(pos+1,x1+1,x2));
	if(dfs(pos+1,x1,x2+1)!=-1)
		temp=max(temp,dfs(pos+1,x1,x2+1));
	if(dfs(pos+1,x1+1,x2+1)!=-1)
		temp=max(temp,dfs(pos+1,x1+1,x2+1));
	ans+=temp;
	return dp[pos][x1][x2]=ans;
}
int solve()
{
	memset(dp,-1,sizeof(dp));
	return dfs(3,2,1)+graph[1][1]+graph[n][m];
}
int main()
{
	int cas,c,i,j;
	scanf("%d",&cas);
	for(c=1;c<=cas;c++)
	{
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				scanf("%d",&graph[i][j]);
			}	
		}
		printf("Case %d: %d\n",c,solve());
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值