hdoj1428 漫步校园

本文介绍了如何解决HDOJ1428问题,该问题在省赛中出现。原解法通过SPFA求最短路和记忆化搜索,但导致超时。改进方法是在原矩阵上使用宽度优先搜索(BFS)优化最短路,结合记忆化搜索,避免了超时问题。
摘要由CSDN通过智能技术生成

这题居然是我们省赛的一题。。一模一样,早做了这题就好了,orz。。。。


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1428


我比赛时是先转换为图后用spfa求最短路的,再用记忆化搜索做的,结果超时。。。。

其实不用转为图(转化为图再做最短路会浪费大量时间),直接用再原矩阵的基础上用宽搜做(队列优化)最短路,再记忆化搜索,就不会超时。


具体代码如下:

#include<iostream>
using namespace std;
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue> 

#define N 51

struct node{
       
     int x,y;   
     node(int a,int b)
     {
         x=a; y=b;     
     }    
     node(){};      
};

int key[4][2]={0,1,0,-1,1,0,-1,0};

int n,map[N][N],d[N][N];
long long f[N][N];

void find()
{
     int i;
     node s;
     
     queue<node> Q;
     
     memset(d,1,sizeof(d));
     d[n][n]=map[n][n];
     Q.push(node(n,n));
     
     while (!Q.empty())
     {
          s=Q.front(); 
          Q.pop();
          
          for (i=0;i<4;++i)
              {
              int x,y;
              x=s.x+key[i][0]; y=s.y+key[i][1];
              if (x>0&&x<=n && y>0&&y<=n)
                 {
                 if (d[x][y]>d[s.x][s.y]+map[x][y])
                     {
                     d[x][y]=d[s.x][s.y]+map[x][y];
                     Q.push(node(x,y));                              
                     }       
                 }
                           
              }
     }     
}

long long dp(int x,int y)
{
    if (f[x][y]!=-1) return f[x][y];
    int i;
    long long t=0;
    for (i=0;i<4;++i)
        {
        int x1,y1;
        x1=x+key[i][0]; y1=y+key[i][1];
        if (x1>0&&x1<=n && y1>0&&y1<=n)
           if (d[x1][y1]<d[x][y])
              {
              t+=dp(x1,y1);            
              } 
        }    
    return f[x][y]=t;
}

int main()
{
    
    while (~scanf("%d",&n))
    {
    int i,j; 
    for (i=1;i<=n;++i)      
        for (j=1;j<=n;++j)
            scanf("%d",&map[i][j]);      
    
    find();
   
    memset(f,-1,sizeof(f));
    f[n][n]=1;
    dp(1,1); 
    
    printf("%I64d\n",f[1][1]);    
    }


    return 0; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值