动态规划(一)

题目描述

假设有排成一行的N个位置,记为1~N,N一定大于或等于2

开始时机器人在其中的M位置上(M一定是1~N中的一个)

如果机器人来到1位置,那么下一步只能往右来到2位置;

如果机器人来到N位置,那么下一步只能往左来到N-1位置;

如果机器人来到中间位置,那么下一步可以往左走或者往右走;

规定机器人必须走K步,最终能来到P位置(P也是1~N中的一个)的方法有多少种

给定四个参数N、M、K、P,返回方法数。

暴力递归

机器人当前来到的位置是cur

机器人还有rest步要走

最终目标是aim

位置1~n

返回:机器人从cur出发,走过rest步以后,最终停在aim的方法数是多少?

#include <bits/stdc++.h>

using namespace std;


int process1(int cur,int rest,int aim,int n)
{
    if(rest == 0){//如果没有步数要走,走完了
        return cur == aim  ? 1:0;
    }
    //rest > 0, 还需要走
    if(cur == 1){//1 -> 2
        return process1(2, rest - 1, aim, n);
    }
    if(cur == n){//n-1 <- n
        return process1(n-1, rest - 1, aim, n);
    }
    //机器人在中间位置
    return process1(cur - 1, rest - 1, aim, n) + process1(cur + 1, rest - 1, aim, n);

}

int main()
{
    cout << process1(2, 4, 4, 4);
    //3

    return 0;

}

缓存法

cur范围:1 ~ n

rest范围:0 ~ k

dp是缓存表 n+1*k+1

dp[cur][rest] == -1 -> process1(cur , rest)之前没算过!

dp[cur][rest] != -1 -> process1(cur , rest)之前算过!返回值在dp[cur][rest];

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


int process2(int cur,int rest,int aim,int n,int dp[][])
{
    if (dp[cur][rest] != -1) {
        return dp[cur][rest];
    }
    //之前没算过!
    int ans = 0;

    if (rest == 0) {
        ans == cur == aim ? 1 : 0;
    } else if(cur == 1){
        ans = process2(2, rest - 1, aim, n, dp);
    } else if(cur == n){
        ans = process2(n-1, rest - 1, aim, n, dp);
    } else {
        process2(cur - 1, rest - 1, aim, n, dp)+ process2(cur + 1, rest - 1, aim, n, dp);
    }

    ans = dp[cur][rest];

    return ans;
}

int ways2(int n,int start,int aim,int rest)
{
    int dp[n + 1][rest + 1];
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j <= rest; ++j) {
            dp[i][j] = -1;
        }
    }

    return process2(start, rest, aim, n, dp);
}
int main()
{
    cout << ways2(2, 4, 4, 4);

    return 0;}

动态规划

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

int ways3(int N, int start, int aim, int K){
    int dp[105][105];
    dp[aim][0] = 1;
    for(int rest = 1; rest <= K; rest++){
        dp[1][rest] = dp[2][rest - 1];
        for(int cur = 2; cur < N; cur++){
            dp[cur][rest] = dp[cur - 1][rest - 1] + dp[cur + 1][rest - 1];
        }
        dp[N][rest] = dp[N - 1][rest- 1];
    }
    return dp[start][K];

}
int main()
{

    int temp = ways3(5, 2, 4, 6);
    cout << temp << endl;

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值