课后自主练习(递归)1058. 地铁站 medium《编程思维与实践》个人学习笔记

题目

在这里插入图片描述

思路

不完全归纳法
在这里插入图片描述
不难发现
f ( n ) = f ( n − 1 ) + f ( n − 2 ) u p f(n) = f(n - 1) + f(n-2)_{up} f(n)=f(n1)+f(n2)up
f ( n ) u p = f ( n − 1 ) u p + f ( n − 2 ) u p f(n)_{up} = f(n-1)_{up}+ f(n-2)_{up} f(n)up=f(n1)up+f(n2)up
所以这个题目用迭代更好,用递归的话只能解出来每一段的delta,如果是解出delta再累加那时间复杂度太高了,其实不如迭代来的快

代码(递归)


#define ll long long
using namespace std;

 int A[4] {1,0,1,0};
 int B[4] {0,0,0,1};



ll CALDb(int times)
{
    if(times == 1)
    {
        return B[0];
    }
    if(times == 2)
    {
        return B[0];
    }
    if(times == 3)
    {
        return B[0];
    }
    if(times == 4)
    {
        return B[3];
    }
    //cout << times << endl;
    return CALDb(times - 1) + CALDb(times - 2);
}

ll CALDa(int times)
{
    if(times == 1)
    {
        return A[0];
    }
    if(times == 2)
    {
        return A[1];
    }
    if(times == 3)
    {
        return A[2];
    }
    if(times == 4)
    {
        return A[3];
    }
    //cout << times << endl;
    return CALDa(times - 1) + CALDa(times - 2);
}

ll calcoea(int a)
{
    if(a == 1) return 1;
    if(a == 2) return 1;
    if(a == 3) return 2;
    if(a == 4) return 2;
    return CALDa(a) + calcoea(a - 1);
}
ll calcoeb(int b)
{
    if(b < 4) return 0;
    if(b == 4) return 1;
    return CALDb(b) + calcoeb(b - 1);
}

int main()
{
    int a;
    int n;
    int m;
    int x;
    cin >> a >> n >> m >> x;
    
    ll b = (m - a * calcoea(n - 1)) / calcoeb(n - 1);
    //cout << "b " << b << " a " << a << endl;//

    // for(int i = 3; i< 10; i++)
    // {
    //     cout << "b " << calcoeb(i) << " a " << calcoea(i) << endl;//
    // }
    ll people = calcoeb(x)* b + calcoea(x) * a;
    cout << people << endl;


    return 0;
}

代码(迭代)

#include<iostream>

#define ll long long
using namespace std;

struct STA
{
    long long coea = 0;
    long long coeb = 0;
    ll da = 0;
    ll db = 0;

    ll upa = 0;
    ll upb = 0;
    
};
//
int main()
{
    int a;
    int n;
    int m;
    int x;
    cin >> a >> n >> m >> x;
    STA * sta = new STA[n];
    sta[0].coea = 1;
    sta[1].coea = 1;
    sta[0].upa = 1;
    sta[1].upb = 1;
    for(int i = 2; i < n; i++)
    {
        sta[i].upa = sta[i - 1].upa + sta[i - 2].upa;
        sta[i].upb = sta[i - 1].upb + sta[i - 2].upb;

        sta[i].da = sta[i - 2].upa;
        sta[i].db = sta[i - 2].upb;

        sta[i].coea = sta[i].da + sta[i - 1].coea;
        sta[i].coeb = sta[i].db + sta[i - 1].coeb;

        //cout <<"coea  " <<sta[i].coea <<"  coeb  "<<sta[i].coeb << endl;

    }
    //a一开始上车 m一开始下车
    //n车站 x车站
    ll b = (m - a * sta[n - 2].coea) / sta[n - 2].coeb;
    cout << "b " << b << " a " << a << endl;

    ll people = sta[x - 1].coeb * b + sta[x - 1].coea * a;
    cout << people << endl;


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值