LightOJ-1071-dp,dfs

来源:互联网 发布:澳洲人工智能专业排名 编辑:程序博客网 时间:2024/05/29 14:17

题目大意:给定一张网格图,起始点为(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