IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> P2532 [AHOI2012]树屋阶梯 (卡特兰数状态转移方程写法) -> 正文阅读

[数据结构与算法]P2532 [AHOI2012]树屋阶梯 (卡特兰数状态转移方程写法)

P2532 [AHOI2012]树屋阶梯

分析:

  • 考虑以阶梯左下角那个点为第一个钢材的左下角,那么第一个钢材摆放情况便如下图(以 n = 5 n=5 n=5 为例)
img
  • 对每种情况分别讨论,那么问题都被分成了两个子问题,设f[n]表示摆放高度为n的台阶的方法数,那么:

f [ 5 ] = f [ 4 ] ? f [ 0 ] + f [ 3 ] ? f [ 1 ] + f [ 2 ] ? f [ 2 ] + f [ 1 ] ? f [ 3 ] + f [ 0 ] ? f [ 4 ] = ∑ x + y = 5 f [ x ] ? f [ y ] ? ( f [ 0 ] = f [ 1 ] = 1 ) f[5]=f[4]*f[0]+f[3]*f[1]+f[2]*f[2]+f[1]*f[3]+f[0]*f[4]=\sum_{x+y=5}f[x]*f[y]\ (f[0]=f[1]=1) f[5]=f[4]?f[0]+f[3]?f[1]+f[2]?f[2]+f[1]?f[3]+f[0]?f[4]=x+y=5?f[x]?f[y]?(f[0]=f[1]=1)

? 显然,这就是卡特兰数

  • 但是这题很烦,还要用高精乘,本人懒得打了,结果在题解里翻到一个神奇的卡特兰数的状态转移方程:

f [ i ] [ j ] = f [ i ? 1 ] [ j ] + f [ i ] [ j ? 1 ] f[i][j]=f[i-1][j]+f[i][j-1] f[i][j]=f[i?1][j]+f[i][j?1]

img

打表的代码:

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

const int N=1005;
int f[N][N];
signed main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    f[1][1]=f[1][2]=1;
    for(int i=2;i<=100;i++)
    {
        for(int j=1;j<=i+1;j++) f[i][j]=f[i-1][j]+f[i][j-1];
        // 这里的 f[i][i+1] 是为了保证下一行 f[i+1][i+1]的正确性 
    }
    for(int i=1;i<=10;i++)
    {
        for(int j=1;j<=i;j++)
        {
            printf("%-5d",f[i][j]);
        }printf("\n");
    }

    return 0;
}

还可以压缩为一维的,本身就是不断迭代的过程
f [ i ] = f [ i ] + f [ i ? 1 ] f[i]=f[i]+f[i-1] f[i]=f[i]+f[i?1]

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

int f[1005];
signed main()
{
    f[1]=1;
    for(int i=1;i<=10;i++)
    {
        for(int j=1;j<=i+1;j++)
        {
            f[j]=f[j-1]+f[j];
            if(j==i+1) { printf("\n"); continue; }
            printf("%-5d",f[j]);
        }
    }
    return 0;
}

最后再加上高精加就是本题的代码, f [ n ] [ n ] f[n][n] f[n][n] 第二维表示答案的位数

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

const int N=1005;
int f[N][N];
signed main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    f[1][1]=1;
    int len=1;
    for(int i=2;i<=n+1;i++)
    {
        for(int j=1;j<=i;j++)
        {
            for(int k=1;k<=len;k++)
            {
                f[j][k]+=f[j-1][k];
            }
            for(int k=1;k<=len;k++)
            {
                f[j][k+1]+=f[j][k]/10;
                f[j][k]%=10;
            }
            while(f[j][len+1]) len++;
        }
    }
    for(int i=len;i>=1;i--) cout<<f[n][i];

    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:33:19  更:2021-09-29 10:33:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:39:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码