1. 程式人生 > >poj 1088 dp記憶化搜尋狀態( or dfs)

poj 1088 dp記憶化搜尋狀態( or dfs)


這道滑雪的題當時陳月航他們來講過的,但是忘完了,就只記得這道題是dp+記憶化搜尋

這道題我先用dp遞迴的方式搜出來結果,感覺有點像搜尋的樣子,但是提交上去直接超時

然後我就想到了貌似要用記憶化搜尋,坑了很多次,中間忽略了兩個地方(在程式碼中指出)

其實這道dp和迷宮搜尋很像,都是搜4個方向

這道題的重點就是每搜尋玩一個位置要這個位置搜出的狀態,下次搜到這個位置就可以直接用這個狀態了(dp  的感覺)

坑爹的地方就在於可能同時  到兩個地方所以不能直接 賦值,要進行一次比較。。程式碼中 指出

程式碼如上。。。36ms

Total Submissions: 71463 Accepted:
26394
#include<stdio.h>
int n,m,num[101][101],ans=1,d[101][101]={0},temp=1;
void dp(int i,int j,int x)
{
    if(i>=0&&i<n&&j>=0&&j<m)//把  m寫成了n  wrong了幾次,後面檢查到的
    {

        if(d[i][j]==0)
        {
        if(i+1<n)
        if(num[i+1][j]<num[i][j])
            dp(i+1,j,x+1);

        if(i-1>=0)
        if(num[i-1][j]<num[i][j])
            dp(i-1,j,x+1);

        if(j+1<n)
        if(num[i][j+1]<num[i][j])
            dp(i,j+1,x+1);

        if(j-1>=0)
        if(num[i][j-1]<num[i][j])
            dp(i,j-1,x+1);
        }
        else
        {
            temp=temp>x+d[i][j]-1?temp:x+d[i][j]-1;//這裡沒有考慮到當 dp 到  幾個位置d[i][j]都有值的情況,一直wrong
        }
         temp=temp<x?x:temp;

    }
}
int main()
{

    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            scanf("%d",&num[i][j]);
        }
    }
      for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            temp=1;
           dp(i,j,1);
           d[i][j]=temp;
      //     ans=ans<d[i][j]?d[i][j]:ans;
         ans=ans<temp?temp:ans;

        }
    }
    printf("%d\n",ans);

}