hdu 1428 记忆化搜索

来源:互联网 发布:淘宝双十一2017销售额 编辑:程序博客网 时间:2024/05/22 02:23

做了杭电1428 这道搜索题,记忆化搜索就是 搜索的形式+动态规划的思想。。

 之所以要记忆化,是因为相互之间的拓扑关系较复杂,不是那种严格限制只能向左向右走的。所以用一个dp数组记住。。

下面解释下题意: 从(1,1)走到(n,n)每次可以上,下,左,右四个方向。但是有前提,前提是这样的:假如(1,1)到(n,n)最短耗时为time,那么你接下来走到(x,y)必须保证(x,y)到(n,n)的最短耗时小于time.

所以先以(n,n)为源点,用bfs求出到每一点的最短距离,然后再dfs记忆化搜索。。

#include <iostream>
#include <queue>
using namespace std;
struct node
{
 int x,y,t;
 friend bool operator <(node n1,node n2)
 {
  return n1.t>n2.t;
 }
};
int s[64][64],visit[64][64],dp[64][64],n;
int xx[]={1,-1,0,0};
int yy[]={0,0,1,-1};
bool ok(node p)
{
  return p.x>=1&&p.x<=n&&p.y>=1&&p.y<=n;  
}
bool is_ok(int x,int y)
{
  return x>=1&&x<=n&&y>=1&&y<=n;  
}
void bfs(int x,int y)
{
  priority_queue<node> que;
  node cur,next;
  cur.x=x;
  cur.y=y;
  cur.t=s[x][y];
  visit[x][y]=1;
  que.push(cur); 
  while(!que.empty())
  {
    cur=que.top();
    que.pop();
    for(int i=0;i<4;i++)
     {
       next.x=cur.x+xx[i];
       next.y=cur.y+yy[i];
       if(ok(next)&&!visit[next.x][next.y])
       {
          visit[next.x][next.y]=1;
          s[next.x][next.y]+=cur.t;
          next.t=s[next.x][next.y];
          que.push(next); 
       }
     }
  }
    
}
int  dfs(int x,int y)
{
  if(dp[x][y])return dp[x][y];    
  for(int i=0;i<4;i++)
  {
      int tx=x+xx[i];
      int ty=y+yy[i];
      if(s[x][y]>s[tx][ty]&&is_ok(tx,ty))
        dp[x][y]=dfs(tx,ty);
        
  }
 return dp[x][y];
}
int main()
{
  while(cin>>n)
  {
    memset(visit,0,sizeof(visit));
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      cin>>s[i][j];
      bfs(n,n);
      dp[n][n]=1;
    cout<<dfs(1,1)<<endl; 
       
  }
  return 0;  
}

0 0