二刷算法基础题DAY7

11 篇文章 0 订阅
  1. 递归实现指数型枚举
    题目链接
#include<iostream>

using namespace std;

const int N=20;

int n;
int f[N];
void dfs(int index){
    if(index>n){
        for(int i=1;i<=n;i++){
            if(f[i])
                cout<<i<<" ";
        }
        cout<<endl;
        return ;
    }
    f[index]=1;
    dfs(index+1);
    f[index]=0;
    dfs(index+1);
}

int main(){
    cin>>n;
    dfs(1);
    return 0;
}
  1. 递归实现组合型枚举
    题目链接
#include<iostream>
using namespace std;
const int N = 1000;

int f[N];
int n, m;
int cnt = 0;
int res[N];

void dfs(int index) {
    if(cnt==m){
        for(int i=1;i<=cnt;i++){
            cout<<res[i]<<" ";
        }
        cout<<endl;
        return ;
    }
    for(int i=1;i<=n;i++){
        if(!f[i]&&i>res[cnt]){
            f[i]=1;
            cnt++;
            res[cnt]=i;
            dfs(i+1);
            f[i]=0;
            cnt--;
        }
    }
    
}


int main() {
    cin >> n >> m;
    dfs(1);
    return 0;
}
  1. 递归实现排列型枚举
    题目链接
#include<iostream>
#include<algorithm>
using namespace std;

const int N=1000;

int f[N];

int n;
int cnt;
int res[N];
void dfs(int index){
    if(cnt==n){
        for(int i=1;i<=n;i++){
                cout<<res[i]<<" ";
        }
        cout<<endl;
    }
    
    for(int i=1;i<=n;i++){
        if(!f[i]){
            cnt++;
            f[i]=1;
            res[cnt]=i;
            dfs(i);
            f[i]=0;
            cnt--;
        }
    }
    
}



int main(){
    cin>>n;
    dfs(1);
    
    return 0;
}

剑指 Offer 10- II. 青蛙跳台阶问题
题目链接

这题纯粹的dfs是过不了的

class Solution {
public:
    int f[105]; 
    int dfs(int n){
        if(f[n]) return f[n];
        if(n==0) return 1;
        if(n==1) return 1;
        if(n==2) return 2;
        f[n-1]=dfs(n-1)%1000000007;
        f[n-2]=dfs(n-2)%1000000007;

        return (dfs(n-1)%1000000007+dfs(n-2)%1000000007)%1000000007;

    }

    int numWays(int n) {
        return dfs(n);
    }
};
  1. 第 N 个泰波那契数
    题目链接
class Solution {
public:
    int f[50];

    int dfs(int n){
        if(n==0) return 0;
        if(n==1 || n==2)    return 1;
        if(f[n])    return f[n];
        f[n-1]=dfs(n-1);
        f[n-2]=dfs(n-2);
        f[n-3]=dfs(n-3);
        return f[n-1]+f[n-2]+f[n-3];
    }
    int tribonacci(int n) {
        return dfs(n);
    }
};
  1. 滑雪 ()
    题目链接
    同类型题

超时代码dfs

#include<iostream>

using namespace std;

const int N=300 +10;

int a[N][N];
int vis[N][N];
int n,m;
int ff=0;
void dfs(int x, int y, int res){
    ff=max(ff,res);
    vis[x][y]=1;
    int res1=0,res2=0,res3=0,res4=0;
    if(x+1<=n && a[x][y]>a[x+1][y]){
        dfs(x+1,y,res+1);
    }
    
    if(y+1<=m&&a[x][y]>a[x][y+1]){
        dfs(x,y+1,res+1);
    }
    
    if(x-1>0&&a[x][y]>a[x-1][y]){
        dfs(x-1,y,res+1);
    }
    
    if(y-1>0&&a[x][y]>a[x][y-1]){
        dfs(x,y-1,res+1);
    }

}

int main(){
    int r=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int v=1;v<=n;v++){
            for(int u=1;u<=m;u++){
                vis[v][u]=0;
            }
        }
        for(int j=1;j<=m;j++){
            dfs(i,j,0);
        }
    }
    cout<<ff+1;
    
    
    
    return 0;
}

AC代码,记忆化搜索优化

#include<iostream>

using namespace std;

const int N=300 +10;

int a[N][N];
int vis[N][N];
int memo[N][N];
int n,m;
int ff=0;
int dfs(int x, int y, int res){
    if(memo[x][y]){
        return memo[x][y];
    } 
    
    memo[x][y]=vis[x][y]=1;
    int res1=0,res2=0,res3=0,res4=0;
    if(x+1<=n && a[x][y]>a[x+1][y]){
       memo[x][y]=max(memo[x][y],dfs(x+1,y,res)+1);
    }
    
    if(y+1<=m&&a[x][y]>a[x][y+1]){
         memo[x][y]=max(memo[x][y],dfs(x,y+1,res)+1);
    }
    
    if(x-1>0&&a[x][y]>a[x-1][y]){
         memo[x][y]=max(memo[x][y],dfs(x-1,y,res)+1);
    }
    
    if(y-1>0&&a[x][y]>a[x][y-1]){
         memo[x][y]=max(memo[x][y],dfs(x,y-1,res)+1);
    }
    return  memo[x][y];
}

int main(){
    int r=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int v=1;v<=n;v++){
            for(int u=1;u<=m;u++){
                vis[v][u]=0;
            }
        }
        for(int j=1;j<=m;j++){
            ff=max(ff,dfs(i,j,0));
        }
    }
    cout<<ff;
    
    
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值