【思特奇杯·云上蓝桥-算法集训营】第3周

1.斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你 n ,请计算 F(n) 。

示例 1:

输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fibonacci-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

int fib(int n){
    if(n==0)
        return 0;
    if(n==1)
        return 1;
    int f[n+1];
    f[0]=0;
    f[1]=1;

    for(int i=2;i<=n;i++)
        f[i]=f[i-1]+f[i-2];

    return f[n];
}

2. 泰波那契序列 Tn 定义如下: 

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

示例 1:

输入:n = 4
输出:4
解释:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-th-tribonacci-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

int tribonacci(int n){
    if(n==0)
        return 0;
    if(n==1)
        return 1;
    if(n==2)
        return 1;
    
    int f[n+1];
    f[0]=0;
    f[1]=1;
    f[2]=1;

    for(int i=3;i<=n;i++)
        f[i]=f[i-1]+f[i-2]+f[i-3];
    
    return f[n];
}

3. 

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

int f[46]={0,1,2,0};

int climbStairs(int n){
    if(f[n]>0)
        return f[n];
    else 
        return f[n] = climbStairs(n-1) + climbStairs(n-2);
}

4.

你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

示例 1:

输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int a[1001]={0};


        for(int i=2;i<cost.size()+1;i++)
            a[i]=min(a[i-1]+cost[i-1],a[i-2]+cost[i-2]);
        
        return a[cost.size()];
    }
};

5.

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
    if(prices.size()<=1)
        return 0;
    int max1=prices[1]-prices[0];
    int min1=prices[0];

    for(int i=0;i<prices.size()-1;i++)
    {   
        min1=min(min1,prices[i]);
        max1=max(max1,prices[i+1]-min1);

    }
    if(max1>0)
        return max1;
    else 
        return 0;
    }
};

6.

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace" ,它的长度为 3 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/qJnOS7
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int c[1000][1000]={0};
        int m=text1.size();
        int n=text2.size();

        text1=' ' + text1 ;
        text2= ' ' + text2;
        int i=1,j=1;
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(text1[i]==text2[j])
                    c[i][j]=c[i-1][j-1]+1;
                else
                    c[i][j]=max(c[i-1][j],c[i][j-1]);
                
            }
        }
        return c[m][n];
    }
};

7. 蓝桥杯-杨辉三角形

#include <iostream>
#include <vector>
using namespace std;

int main()
{   
    vector<vector<int> > a;
    int sum=3,aim,n,flag=0;
    cin >> aim;
    if(aim==1)
    {
        cout << 1;
        return 0;
    }
   a.push_back(vector<int>());
   a.push_back(vector<int>());
    a.push_back(vector<int>());
    a[0].push_back(1);
    a[1].push_back(1);
    a[1].push_back(1);
    for(int i=2;;i++)
    {
        for(n=0;n<i+1;n++)
        {
            if(n==0 || n==i)
                a[i].push_back(1);
            else
                a[i].push_back(a[i-1][n-1]+a[i-1][n]);  
            
            sum++;
            if(aim==a[i][n])
            {
                flag=1;
                break;
            }
        }
        a.push_back(vector<int>());
        if(flag==1)
            break;
    }
    cout << sum;
    return 0;
}

8.蓝桥杯-节点选择


#include <iostream>
#include <vector>
 using namespace std;
 
 int n;
 int dp[100005][2];
int color[100005];
 vector<int> vt[100005];

 void DFS(int st)
{   
    color[st]=1;
   for(int i=0;i<vt[st].size();i++)
    {
        int next=vt[st][i];
        if(!color[next])
        {
            DFS(next);
            dp[st][1]+=dp[next][0];
            dp[st][0]+=max(dp[next][0],dp[next][1]);
        }
      
    }
 }
 
int main()
{    
    cin >> n;
    
    for(int i=0;i<n;i++)
       cin >> dp[i][1];
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        vt[a].push_back(b);
        vt[b].push_back(a);
    }
    DFS(1);
    printf("%d\n",max(dp[1][0],dp[1][1]));
    cout << endl << dp[1][1] ;
     return 0;
}

9.

耐摔指数 x 星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。 塔的各层高度都是一样的。他们的第 1 层不是地面,而是相当于我们的 2 楼。 他们的地面层为 0 层。如果手机从第 7 层扔下去没摔坏,但第 8 层摔坏了,则 手机耐摔指数 = 7。 特别地,如果手机从第 1 层扔下去就坏了,则耐摔指数 = 0。 如果到了塔的最高层第 n 层扔没摔坏,则耐摔指数 = n。 为了加快测试进度,从每个型号手机中,抽样 3 部参加测试。 问题来了:如果已知了测试塔的高度 n,并且采用最佳的策略,在最坏的运气下 需要测试多少次才能确定手机的耐摔指数呢

#include <iostream>
using namespace std;
#define M 20000
int main()
{
    int n;
    cin >> n;
    int dp[10][M]= {0};
    int m = 3, i,  j,  k;
    for(j = 1; j <= n; j++)
        dp[1][j] = j;
    
    for(i = 2; i <= m; i ++)
    {
        for(j = 1; j <= n; j++)
        {
            dp[i][j] = j;
            for(k = 1; k <= j; k++)
            {
                int num = max(1+dp[i-1][k-1], 1+dp[i][j-k]);
                dp[i][j] = min(dp[i][j], num);
            }
        }
    }
    printf("%d", dp[m][n]);
    return 0;
}

10.蓝桥杯-K好数

#include<iostream>
#include<cstring>
using namespace std;

void K()
{
    int n,l,sum=0;
    cin>>n>>l;
    l--;
    long long  dp[2][n];

    memset(dp,0,sizeof(dp));

    for(int i=0;i<n;i++)
    {

        if(i==0||i==n-1)
            dp[0][i]=n-1;

        else
            dp[0][i]=n-2;

    }

    for(int k=1;k<l;k++)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(j==0)
                    dp[k&1][i]=0;
                if(j!=i-1&&j!=i+1)
                  dp[k&1][i]+=dp[~k&1][j]%1000000007;
            }
        }
    }

    for(int i=1;i<n;i++)

    {
        sum+=dp[~l&1][i]%1000000007;
        sum=sum%1000000007;
    }
    cout<<sum%1000000007<<endl;

}

int main()
{
    K();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值