刷题记录:洛谷 P1216 数字三角形

日期:2025-05-05

题型:动态规划 DP 入门题
难度:普及/提高−

题目大意

给定一个数字三角形,从顶部出发,每一步只能向左下或右下走,求走到最底层路径上数字和的最大值。

洛谷P1216题目截图

解题思路

从上到下dp代码展示

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

const int MAXN=1005;
int a[MAXN][MAXN];//存原始三角塔
int dp[MAXN][MAXN];

int main(){
    int r;
    cin>>r;
    for(int i=1;i<=r;i++){//读入每一行
        for(int j=1;j<=i;j++){//第i行有i个数
            cin>>a[i][j];
        }
    }
    dp[1][1]=a[1][1];//初始化起点
    for(int i=2;i<=r;i++){//处理边界
        dp[i][1]=dp[i-1][1]+a[i][1];//每行最左的
        dp[i][i]=dp[i-1][i-1]+a[i][i];//每行最右
    }
    for(int i=3;i<=r;i++){//开始有中间数值处理
        for(int j=2;j<i;j++){
            dp[i][j]=a[i][j]+max(dp[i-1][j-1],dp[i-1][j]);//存档+max
        }
    }
    int result =0;
    for(int j=1;j<=r;j++){//遍历最后一行,找最大值
        result=max(result,dp[r][j]);
    }
    cout<<result<<endl;
    return 0;
}

从下到上dp代码展示

#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=1005;
int a[MAXN][MAXN];
int dp[MAXN][MAXN];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin>>a[i][j];
    for(int j=1;j<=n;j++)//初始化最后一行
        dp[n][j]=a[n][j];
 
    for(int i=n-1;i>=1;i--)//从下向上,无需考虑边界问题
        for(int j=1;j<=i;j++)
            dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
    
    cout<<dp[1][1]<<endl;
    return 0;
}

刷题记录2:力扣153 旋转数组找最小值

题型:二分查找变形
难度:中等

题目大意

给出升序的一个数组,找出其围绕中位旋转某次后的最小值

力扣153题目截图

解题思路

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

int main() {
    ios::sync_with_stdio(false);//关闭同步,加速 cin/cout
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i <n;++i){
        cin >> nums[i];
}
    int l=0, r=n-1;
    while (l < r) {
        int mid=l+(r-l)/2; //防溢出
        if (nums[mid] > nums[r])//最小值在右
            l = mid+1;
        else
            r = mid;
    }

    cout << nums[l] << endl;
    return 0;
}

今日总结


← 返回我的学习主页