1 条题解
-
0
#include<bits/stdc++.h> using namespace std; int n; // [1] n-输入的序列长度 int arr[1100]; // [2] arr数组-存储输入的序列元素(下标从1开始,对应第1到第n个元素) int dp[1100]; // [3] dp数组-动态规划数组,dp[i]表示以第i个元素结尾的最大上升子序列和 int main(){ cin>>n; // [4] 读取序列长度n for(int i=1;i<=n;i++) cin>>arr[i]; // [5] 读取n个序列元素,存入arr数组(下标1对应第一个元素) /* 问题分析:求「最大上升子序列和」,这里的上升子序列是**不连续**的,且元素严格递增。 核心思路:对每个元素arr[i],计算以它结尾的最大上升子序列和dp[i],再取所有dp[i]的最大值。 每个元素有两种选择: (1) 自己作为新子序列的开头,此时dp[i] = arr[i] (2) 接在前面某个比它小的元素arr[j](j < i)的子序列后面,此时dp[i] = dp[j] + arr[i] */ memset(dp,0,sizeof(dp)); // [6] 初始化dp数组为0,确保初始状态干净 dp[0]=0; // [7] 边界条件:前0个元素(无元素)的子序列和为0 int max_num=0;// [8] max_num-记录全局最大上升子序列和(所有dp[i]中的最大值) // 遍历每个元素,计算以它结尾的最大上升子序列和 for(int i=1;i<=n;i++){ // 第一种情况:当前元素自己作为新子序列的开头 dp[i]=arr[i]; // [9] 初始化为自身值,因为可以单独构成子序列 // 第二种情况:尝试接在前面符合条件的子序列后面 for(int j=i-1;j>=1;j--){ if(arr[i]>arr[j]){ // [10] 只有当arr[i] > arr[j]时,才能接在arr[j]的子序列后面(保证上升) dp[i]=max(dp[i],dp[j]+arr[i]); // [11] 取“自己开头”和“接在j后面”的最大值,更新dp[i] } } max_num=max(max_num,dp[i]);// [12] 更新全局最大值,确保找到所有可能的子序列和中的最大值 } cout<<max_num; // [13] 输出全局最大上升子序列和 return 0; }
- 1
信息
- ID
- 1323
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 2
- 上传者