zoukankan      html  css  js  c++  java
  • 记忆化搜索(hdu1078)

    记忆化搜索实际上是递归来实现的,但是递归的过程中有许多的结果是被反复计算的,这样会大大降低算法的执行效率,因此我们可以将已经计算出来的结果开辟一个数组dp[][]保存起来,当之后的计算用到的时候直接取出结果,避免重复运算,从而提高效率。

    比如HUD1078:
    题意:给出n*n的格子,每个格子有食物,问一只老鼠每次走最多k步所能吃到的最多的食物,而且,每次吃的食物要比上一次多(加一个判断,后一个格子里的食物>前一个格子里的)

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    int m[110][110],dp[110][110],to[4][2]= {0,1,1,0,-1,0,0,-1 };
    int k,n;
    int dfs(int x,int y)
    {
    	int tx,ty,i,j;
    	if (dp[x][y])
    		return dp[x][y];//如果搜索过了,dp就会有值, 
    					//而且这个值是四周搜索过后的最大值。直接返回储存值就可以
           //没有搜索过的话开始搜索,从当前点向四周搜		 
    	for (i=0; i<4; i++)
    	{
    		for (j=1; j<=k; j++)//每次走的步数
    		{
    			tx=x+to[i][0]*j;
    			ty=y+to[i][1]*j;
    			if (tx>=0&&tx<n&&ty>=0&&ty<n)//下个节点
    			{
    				if (m[tx][ty]>m[x][y])
    				{
    					dp[x][y]=max(dp[x][y],dfs(tx,ty)+m[tx][ty]);
    					// 后个节点的食物大于前个节点,可以走,接下来看看能不能取到最优
    				}
    			}
    		}
    	}//没有搜索过,寻找四周落脚点的最大值储存,然后下一步。 
    	return dp[x][y];
    }
    int main()
    {
    	while(~scanf("%d %d",&n,&k))
    	{
    		if (n==-1&&k==-1)
    		break;
    		int i,j;
    		memset(m,0,sizeof(m));
    		memset(dp,0,sizeof(dp));
    
    		for (i=0; i<n; i++)
    		{
    			for (j=0; j<n; j++)
    				scanf("%d",&m[i][j]);
    		}
    		printf("%d
    ",dfs(0,0)+m[0][0]);
    	}
    	return 0;
    }
  • 相关阅读:
    广商博客冲刺第六七天new
    广商博客沖刺第一天(new ver):
    20150529项目之典型用户与场景
    冲刺第二,三,四,五,六天
    冲刺第一天:
    Android 學習之旅!(2)
    20150512 作业6 团队项目之需求
    Android 學習之旅!(1)
    20150421 作业5 四则运算 测试与封装 5.1 5.2(doing)
    20150421 作业5 四则运算 测试与封装 5.1
  • 原文地址:https://www.cnblogs.com/shidianshixuan/p/13729854.html
Copyright © 2011-2022 走看看