• 记忆化搜索专题


    思想

    记忆化搜索的思想无非就是:搜索 + DP

    注意!!!

    1. 记忆化搜索要判断是从起点直接搜dfs(0,0)还是for循环遍历每一个点都要去搜!
    2. 判断是否需要标记book,还是book直接作为搜到已经搜过的直接返回的数组!

    POJ1088-滑雪

    注意:POJ上不能用万能头文件,把头文件注释掉之后用C++提交会无法提交(直接报错:error: bits/stdc++.h: No such file or directory,必须删除才可以。(为啥我也不晓得)

    必须删除前几行注释掉的部分:

    //#include<bits/stdc++.h>
    //using namespace std;
    //typedef long long ll;
    
    

    AC代码:

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<cmath>
    #include<list>
    #include<stdlib.h>
    #include<map>
    #include<stack>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define sc(T) scanf("%d",&T)
    #define scc(x,y) scanf("%d %d",&x,&y)
    #define pr(T) printf("%d
    ",T)
    #define f(a,b,c) for (int a=b;a<c;a++)
    #define ff(a,b,c) for (int a=b;a>c;a--)
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define eps 1e-9
    #define PI acos(-1)
    
    int a[110][110],n,m,ans,book[110][110];
    int to[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
    
    //void dfs(int x,int y,int cnt)
    int dfs(int x,int y)
    {
    //    if(cnt<=ans)
    //        return;
    //    ans=max(ans,cnt);
        if(book[x][y])
            return book[x][y];
        //book[x][y]=1;
        f(i,0,4)
        {
            int tx=x+to[i][0];
            int ty=y+to[i][1];
    //      if(tx>=0&&tx<n&&ty>=0&&ty<m&&!book[tx][ty])
            if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]<a[x][y])
            {
                // book[tx][ty]++; // book[tx][ty]=1;
    
                //book[tx][ty]=max(book[tx][ty],dfs(tx,ty));
                book[x][y]=max(book[x][y],dfs(tx,ty)+1);
    
                //book[tx][ty]--; // book[tx][ty]=0;
            }
        }
        return book[x][y];
    }
    
    int main()
    {
        cin>>n>>m;
        f(i,0,n)
        {
            f(j,0,m)
            cin>>a[i][j]; 
        }
    //    dfs(0,0,0);
        ans=0; //小于等于0即可
        f(i,0,n)
        {
            f(j,0,m)
            ans=max(ans,dfs(i,j));
        }
        cout<<ans+1<<endl;
        return 0;
    }
    

    HDU1078-FatMouse and Cheese

    题意:自行百度。
    AC代码:

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<cmath>
    #include<list>
    #include<stdlib.h>
    #include<map>
    #include<stack>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define sc(T) scanf("%d",&T)
    #define scc(x,y) scanf("%d %d",&x,&y)
    #define pr(T) printf("%d
    ",T)
    #define f(a,b,c) for (int a=b;a<c;a++)
    #define ff(a,b,c) for (int a=b;a>c;a--)
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define eps 1e-9
    #define PI acos(-1)
    
    int n,k,ans,a[110][110],book[110][110];
    int to[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
    
    int dfs(int x,int y)
    {
        if(book[x][y])
            return book[x][y];
        f(i,0,4)
        {
            f(j,0,k+1)
            {
                int tx=x+to[i][0]*j;
                int ty=y+to[i][1]*j;
                if(tx>=0&&tx<n&&ty>=0&&ty<n&&a[tx][ty]>a[x][y])
                    book[x][y]=max(book[x][y],dfs(tx,ty));
            }
        }
        //return book[x][y];
        return book[x][y]+=a[x][y];
    }
    
    int main()
    {
        while(~scc(n,k),n!=-1||k!=-1)
        {
            mem(book,0);
            f(i,0,n)
            {
                f(j,0,n)
                sc(a[i][j]);
            }
            int w=dfs(0,0);
            //cout<<w<<endl;
            cout<<book[0][0]<<endl;
        }
        return 0;
    }
    

    HDU1978-How many ways

    记忆化搜索Ac代码:

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<cmath>
    #include<list>
    #include<stdlib.h>
    #include<map>
    #include<stack>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define sc(T) scanf("%d",&T)
    #define scc(x,y) scanf("%d %d",&x,&y)
    #define pr(T) printf("%d
    ",T)
    #define f(a,b,c) for (int a=b;a<c;a++)
    #define ff(a,b,c) for (int a=b;a>c;a--)
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define eps 1e-9
    #define PI acos(-1)
    
    #define mod 10000 //写1e4会报错 可以const int mod=1e4不会报错
    int n,m,ans,a[110][110],book[110][110];
    int to[2][2]= {{0,-1},{1,0}};
    
    int dfs(int x,int y)
    {
        if(book[x][y]!=-1)
            return book[x][y];
        book[x][y]=0;
    //    if(x==n-1&&y==m-1)
    //    {
    //        ans++;
    //        return 0;
    //    }
    //    f(i,0,2)
    //    {
    //        int tx=x+to[i][0];
    //        int ty=y+to[i][0];
    //        if(tx>=0&&tx<n&&ty>=0&&ty<m)
    //            book[x][y]=(book[x][y]%mod+dfs(tx,ty)%mod)%mod;
    //
    //    }
        for(int i=0; i<=a[x][y]; i++)
        {
            for(int j=0; j<=a[x][y]-i; j++) //表示消耗那个格子的能量能到达的格子;
            {
                int tx=x+i;
                int ty=y+j;
                if(tx>=0&&tx<n&&ty>=0&&ty<m)
                    book[x][y]=(book[x][y]+dfs(x+i,y+j))%mod;
            }
        }
        return book[x][y];
    }
    
    int main()
    {
        int T;
        sc(T);
        while(T--)
        {
            mem(book,-1);
            ans=0;
            scc(n,m);
            f(i,0,n)
            {
                f(j,0,m)
                sc(a[i][j]);
            }
    //        f(i,0,n)
    //        {
    //            f(j,0,m)
    //            dfs(i,j);
    //        }
            book[n-1][m-1]=1;
            dfs(0,0);
            cout<<book[0][0]%mod<<endl;
        }
        return 0;
    }
    

    这题也可以用DP写,
    DP AC代码:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<string.h>
    #include<queue>
    #include<iostream>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int mod=1e4;
    
    int a[110][110],dp[110][110];
    
    int main()
    {
        int t,n,m;
        cin>>t;
        while(t--)
        {
            memset(dp,0,sizeof(dp));
            cin>>n>>m;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    cin>>a[i][j];
                }
            }
            dp[n][m]=1;
            for(int i=n;i>=1;i--)
            {
                for(int j=m;j>=1;j--)
                {
                    for(int p=0;p<=a[i][j]&&(i+p<=n);p++)
                    {
                        int ww=a[i][j]-p;
                        for(int q=0;q<=ww&&(j+q<=m);q++)
                        {
                            if(p==0&&q==0)
                                continue;
                            dp[i][j]=(dp[i][j]+dp[i+p][j+q])%mod;
                        }
                    }
                }
            }
            int w=dp[1][1];
            printf("%d
    ",w);
        }
        return 0;
    }
    
  • 相关阅读:
    gsm at 指令
    wm8976 codec
    【Gym 100971J】Robots at Warehouse
    【XDU1144】合并模板
    腾讯云CentOS7安装LNMP+wordpress
    【USACO1.1】Broken Necklace
    【校赛小分队之我们有个女生】训练赛6
    【计导作业】——商品记录
    C 文件读写2
    C 文件读写1
  • 原文地址:https://www.cnblogs.com/OFSHK/p/13669715.html
Copyright © 2020-2023  润新知