首页 > 编程语言 >c++踩方格-动态规划基础题

c++踩方格-动态规划基础题

时间:2024-05-12 18:52:01浏览次数:12  
标签:dfs int c++ 五边形 方格 菱形 动态 dp

有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a、每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b、走过的格子立即塌陷无法再走第二次;
c、只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。
输入格式
允许在方格上行走的步数n(n≤20)。
输出格式
计算出的方案数量。
样例:1->3;2->7;3->17。

这道题在最初找第三步的时候,只找到15条,一直很懵逼,怎么网上答案都是17条。后来才发现是我漏了,漏的是和2->3和0->1的路线中3和1重叠,将那个3砍掉了。

这是第二步的路线图,圆形是起点,四边形是第一步的落点,五边形是第二步的落点。
实际上到了第二步,大概的一个关系能够确定,

这是第三步的路线图,三角形是第三步的落点,主要是红色标识的地方,这两个三角形,由于路线不同,不会出现坍塌,要计入的。
接下来就是分析关系了。
初始状态F[0]=1,
走了一步后F[1]=3,
走了两步后F[2]=7,
走了三步后F[3]=17。

走第二步的时候,能够发现所有菱形都至少产生了两个方向的五边形,其中一个菱形产生了三个方向的五边形。F[2]=32+1
走第三步的时候,能够发现所有菱形都至少产生了两个方向的三角形,而有三处菱形产生了三个方向的五边形。F[3]=7
2+3
根据画图,能够发现,上一步的基础上,向上和向左(或者向右)都是存在的,有2F[i-1]。那么多出来的向左(或者向右)是由哪部分产生?
是上上一步的向上箭头产生的图形,才拥有多朝左(或者右)的分支。
比如红圈圈出来的五边形以及顶部的五边形,都是菱形向上箭头产生出来的,而他们都拥有三个分支。往前看,第二步中菱形有三个分支的那处,也是向上箭头产生的。如果对于数据还是不够确定规律,可以继续画第四步,进行验证。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int f[21]={1, 3, 7, 17}, n;
    cin >> n;
    for(int i=3;i<=n;i++){
        f[i]=2*f[i-1]+f[i-2];
    }
    cout << f[n] << endl;
    return 0;
}

递归写法

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

int dfs(int n){
	if(n<1) return 1;
	if(n==1) return 3;
	if(n==2) return 7;
	return 2*dfs(n-1)+dfs(n-2);
}

int main(){
	int n;
	cin >> n;
	cout << dfs(n) << endl;
	return 0;
}

上面那种递归,dfs(2)至少会进入两次,所以可以记忆化搜索

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

int dp[21] = {1, 3, 7};

int dfs(int n) {
	if (n < 1) return 1;
	if (n == 1) return 3;
	if (n == 2) return 7;
	if (dp[n - 1] == 0)  dp[n - 1] = dfs(n - 1);
	if (dp[n - 2] == 0)  dp[n - 2] = dfs(n - 2);
	return 2 * dp[n - 1] + dp[n - 2];
}

int main() {
	int n;
	cin >> n;
	cout << dfs(n) << endl;
	return 0;
}

总的来说,肯定还是第一种使用数组存储更便捷。

标签:dfs,int,c++,五边形,方格,菱形,动态,dp
From: https://www.cnblogs.com/danlis/p/18188054

相关文章

  • C++类型转换
    一、整形提升整型提升是一种隐式类型转换,当涉及到小于int类型的整数(如char、short、bool等)时。整型提升的目的是确保所有的操作数在算术运算或比较操作中具有相同的类型,通常是int类型,如果int不能表示该值,则可能会提升到unsignedint或更大的整数类型。二、无符号数和带符号数进......
  • 【python】bilibili动态删除脚本
    importpprintimportrequestsimportjsonimportreimportos#最大删除条数MAX_COUNT=200#保存cookie的路径COOKIE_FILE_PATH=r"./cookie.txt"classBWebSite(object):def__init__(self):ifnotos.path.exists(COOKIE_FILE_PATH):print("未检测到cooki......
  • Effective C++:2.构造、析构、赋值函数
    几乎每个class都会有一个或者多个构造函数,一个析构函数,一个copyassignment函数,因此有必要加深理解1.条款05:了解C++默默编写并调用哪些函数如果你没有生成一下函数,那么C++会在需要的时候(被调用)帮你自动生成这些函数:default构造函数copy构造函数default析构函数copyassign......
  • 洛谷题单指南-动态规划3-Zuma
    原题链接:https://www.luogu.com.cn/problem/CF607B题意解读:从一组整数中取连续的回文子串,求最少几次可以取完。解题思路:状态表示:设dp[i][j]表示取i~j之间的回文子串所需的最少次数,a[i]表示第i个数状态转移:如果a[i]==a[j],dp[i][j]=dp[i+1][j-1],因为首尾如果相等,其必然可以......
  • 编程竞赛中 C/C++ I/O 的使用
    C的字符串读取scanf以空行为分割进行读取数据。get和fgets以\n为分割读取数据。读取输入直到遇到\n或\0才终止。C++读取字符串cin以空格为分割读取数据。getline默认以换行符为分割读取数据。在使用getline时,要注意处理多个\n连到一块的情况。当读取77\n\n77时,......
  • EasyLogger - 一款超轻量级、高性能的 C/C++ 日志库
    1、EasyLogger-一款超轻量级、高性能的C/C++日志库EasyLogger是一款超轻量级(ROM<1.6K,RAM<0.3K)、高性能的C/C++日志库,非常适合对资源敏感的软件项目,例如:IoT产品、可穿戴设备、智能家居等等。相比log4c、zlog这些知名的C/C++日志库,EasyLogger的功能更加简单,提供......
  • C++_函数式编程-以及常用序列化
    函数式编程函数式编程是一种编程范式,它强调程序的构建是通过应用(applying)和组合函数(composingfunctions)来实现的函数式编程属于“结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用 LambdaCalculus函数式编程语言早期的函数式......
  • C和C++中size sizeof strlen length的对比
    一、sizeof()sizeof是一个操作符,它在编译期间确定的,返回的是静态大小。它可以应用于基本类型、类类型、数组和指针等。例如:sizeof(int)或sizeof(array)。对于数组,sizeof返回整个数组的大小(包括所有元素)。对于指针,sizeof返回指针本身的大小(通常取决于平台和编译器,例如在3......
  • .net5 动态配置
    通过自定义ConfigurationProvider可以实现从数据库获取参数,同时读取配置仍然可以使用原本的IConfiguration添加ConfigProvider处理加载配置及定期刷新配置逻辑///<summary>///配置提供者///</summary>publicclassConfigProvider:ConfigurationProvider,IDispos......
  • gcov - 标准c/c++代码覆盖率测试工具+lcov - GCC测试覆盖率的前端图形展示工具+gprof
    1、advent-calendar-of-circuits-2020-一个月每天用KiCad设计一个PCB项目GregoryDavill是来自澳大利亚的一个技术牛人,在开源硬件领域非常有名且活跃。他在2020年12月坚持每一天设计一个电路板,用KiCad完成电路设计到PCB的布局布线完成,这便是advent-calendar-of-circuits-......