1 条题解

  • 0
    @ 2026-1-27 19:12:08
    #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
    上传者