【思特齐杯.云上蓝桥-算法集训营】第三周

1.斐波那契数列

int dp[n+1];
dp[0] =0;
dp[1] = 1;
for(int i=2;i<=n;i++)
{
    dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
2.第N个泰波那期契数

class Solution {
public:
    vector<int> dp = vector<int>(38,0);
    int func(int idx){
        if(dp[idx] != 0 || idx<=2) return dp[idx];
        dp[idx] = func(idx-1)+func(idx-2)+func(idx-3);
        return dp[idx];
    }
    int tribonacci(int n) {
        dp[1] = 1;
        dp[2] = 1;
        return func(n);
    }
};

3.爬楼梯

class Solution {
    public int climbStairs(int n) {
        if(n==1||n==2){
            return n;
        }
        int f1 = 1;
        int f2 = 2;
        int temp;
        for(int i=3; i<=n; i++){
            temp = f2;
            f2 += f1;
            f1 = temp;
        }
        return f2;  
    }
}

4.使用最小花费爬楼梯

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        if len(cost)==0:
            return 0
        elif len(cost)<=2:
            return min(cost)
        else:
            dp = [cost[0]]*len(cost)
            dp[1] = cost[1]
            for i in range(2,len(cost)):
                dp[i] = min(dp[i-1]+cost[i],dp[i-2]+cost[i])
            return min(dp[-1],dp[-2])
5.买股票的最佳时机

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:
            return 0
        
        buy, sell = -prices[0], 0
        for i in prices[1:]:
            buy = max(buy, -i)
            sell = max(sell, buy + i)

        return sell
6.最长公共子序列

public class LongestCommonSubsequence {
    public int longestCommonSubsequence(String text1, String text2){
         int m=text1.length();
         int n=text2.length();
         int [][]dp=new  int[m+1][n+1];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 获取两个串字符
                char s1 = text1.charAt(i), s2 = text2.charAt(j);
                if (s1 ==s2)//遇到的字符相等
                {
                    dp[i + 1][j + 1] = dp[i][j] + 1;
                }
                else //遇到的字符不相等。
                    {
                    dp[i + 1][j + 1] = Math.max(dp[i + 1][j], dp[i][j + 1]);
                }
            }
        }
        return dp[m][n];
    }
}

7.杨辉三角形

# include<stdio.h>

int main()
{
    int n, i, j;
    /*i是行,j是列*/

    scanf("%d", &n);
    int a[34][34];

    if(n==1){
        printf("1");
    }
    if(n==2){
        printf("1\n");
        printf("1 1");
    }

    if(n>=3)
    {
        for(i=0; i<n; i++){
            a[i][i] = a[i][0] = 1;
        for(j=1; j<=i; j++){
            a[i+1][j] = a[i][j] + a[i][j-1];
        }
        }

        for(i=0; i<n; i ++){
            for(j=0; j<=i; j++){
                printf("%d ",a[i][j]);
            }
            printf("\n");
        }

    }


    return 0;
}
8.节点选择

#include<iostream>
using namespace std;
long long int n;
//我们使用dp[t][1]来记录包括本节点的情况,dp[t][0]表示不包括本节点的情况
long long int dp[100001][2];
//Link是用来记录各个节点之间的关系的
long long int Link[100001][300];


void creat(long long int x, long long int y) {
    int i = 0;
    while (Link[x][i] != 0) {
        i++;
    }
    Link[x][i] = y;

    int j = 0;
    while (Link[y][j] != 0) {
        j++;
    }
    Link[y][j] = x;
}

void tree_dp(int s, int f) {
    int t, k = 0;
    while (t = Link[s][k++]) {
        if (t != f) {
            tree_dp(t, s);
            dp[s][1] = dp[s][1] + dp[t][0];
            dp[s][0] = dp[s][0] + (dp[t][0] > dp[t][1] ? dp[t][0] : dp[t][1]);
        }
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < 100001; i++) {
        for (int j = 0; j < 2; j++) {
            dp[i][j] = 0;
        }
    }
    for (int i = 0; i < 100001; i++) {
        for (int j = 0; j < 300; j++) {
            Link[i][j] = 0;
        }
    }
    //注意下面咱们的i都是要从1开始的,因为0被我们作为一个根节点的父节点了
    for (int i = 1; i <= n; i++) {
        cin >> dp[i][1];
    }
    for (int i = 1; i < n ; i++) {
        long long int x, y;
        cin >> x >> y;
        creat(x, y);
    }
    tree_dp(1, 0);
    cout <<  (dp[1][0] > dp[1][1] ? dp[1][0] : dp[1][1]);
    return 0;
}
9.耐摔指数

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int f2[105],f3[105];
int main(){
    int n;
    while(~scanf("%d",&n)){
        int i=0;
        while(f3[i]<n){
            i++;
            f2[i]=f2[i-1]+i;//这里i本身就++了,所以不用加一了 
            f3[i]=f3[i-1]+f2[i-1]+1;
        }
        cout<<i<<endl; 
    }
    return 0;
}

10.K好数

import java.math.BigInteger;
import java.util.Scanner;

public class Kgood {
    public static BigInteger getNumberOfKGood(int l, int k) {
        // 这是第一步定义的表格的二维数组
        int [][] array = new int[l][k];
        // 这是第二步的初始化,将一位的情况的结果设置为0,1,1,1......
        for (int i = 1; i < k; i++) {
            array[0][i] = 1;
        }
        
        // i代表表格的行,也就是位数
        // j代表表格的列,也就是可能取的进制数
        for (int i = 1; i < l; i++) {
            for (int j = 0; j < k; j++) {
                // 这里为第三步,也就是把这一位所能取的值遍历,并与上一位j做比较,筛选掉相邻的可能
                for (int j2 = 0; j2 < k; j2++) {
                    if ((j != j2 + 1) && (j != j2 - 1)) {
                        // 按题目要求取模
                        array[i][j] = (array[i][j] + array[i-1][j2]) % 1000000007;
                    }
                }
            }
        }
        
        // 最后一步的取值,把最后一行的值加起来就是了
        // 因为数据挺大的,所以遇事不决用大数[滑稽]
        BigInteger sum = new BigInteger("0");
        for (int i = 0; i < k; i++) {
            sum = sum.add(new BigInteger(Integer.toString(array[l - 1][i])));
        }
        return sum.mod(new BigInteger("1000000007"));
    }

    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        int k = sc.nextInt();
        int l = sc.nextInt();
        
        BigInteger sum = getNumberOfKGood(l, k);
        
        System.out.println(sum);
        
        sc.close();
    }
}
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值