关于DP与DFS

Posted emcikem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于DP与DFS相关的知识,希望对你有一定的参考价值。

在二维矩阵上的DFS只有两个方向时,沿着矩形某一个角的方向时,有些问题可以转化为DP来求,同时,这种情况一般无法用DFS来求,因为n与m的值特别大
比如求出从一个角到另一个角的路径有几种
----
下面是求出从左上角到右下角的路径种类

dp[0][1]=1
for(int I=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        dp[i][j]=dp[i-1][j]+dp[i][j-1];
    }
}

初始化的时候注意只初始化起始点即可,不然会和后面的条件冲突
(牛客小白赛就是因为这个原因wa了QAQ)

传送门

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int maxn = 3e3+5;
const int inf = 0x3f3f3f3f;
const int mod = 2333;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}
int n,m;
int dp[maxn][maxn];
int a[maxn][maxn];
void DP(){
    dp[n][0]=1;
    for(int i=n;i>=1;i--){
        for(int j=1;j<=m;j++){
            if(a[i][j]==0)dp[i][j] = (dp[i][j-1]+dp[i+1][j]) % mod;
            else dp[i][j]=0;
        }
    }
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            a[i][j]=read();
        }
    }
    DP();
    cout<<dp[1][m]<<endl;
    return 0;
}

传送门
过河卒也是这个思想
```

以上是关于关于DP与DFS的主要内容,如果未能解决你的问题,请参考以下文章

关于dfs dp 递归的整理

学生的出勤记录II--动态规划和dfs记忆化解决

从dfs暴力->记忆化->子集背包dp->滚动数组优化

树的直径,树形DP,DFS——POJ1958

BNU52325-Increasing or Decreasing-数位DP-DFS

Bzoj2286--Sdoi2011消耗战