浅说线性DP(下)

2024-06-08 1500阅读

声明

最近博主身体不适,更新较慢,请大家体谅体谅

浅说线性DP(下)
(图片来源网络,侵删)

最大上升子序列

【题目描述】

一个数的序列

你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100,1,2,3)的最大上升子序列和为100,而最长上升子序列为(1,2,3)。

【输入】

输入的第一行是序列的长度N(1≤N≤1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。

【输出】

最大上升子序列和。

如果前面的最长上升子序列那道题理解清楚了,那么该题做起来就会发现本质上和前一道题是一样的。该题的决策对象和阶段都和前一道题一样,只是状态变为dp[i]表示以第i个数作为结尾的最大上升子序列的长度。

决策:这里要求子序列之和最大,对于每一个位置的数,只能从前面的比当前值小的数转移过来,要求序列之和最大,那么这个序列前面选择的数之和要最大,那么我们需要从前面可以选择的点中序列和最大的点转移过来。

我们设dp[i]表示以i结尾的最大子序列之和,那么我们就可以很轻松的得到一下内容

d p [ i ] = m a x ( d p [ i ] , d p [ j ] + a [ i ] ) j ∈ [ 1 , i − 1 ] dp[i]=max(dp[i],dp[j]+a[i]) j\in[1,i-1] dp[i]=max(dp[i],dp[j]+a[i])j∈[1,i−1]

所以就有以下ACcode

#include
using namespace std;
int a[10010],dp[10010],ans=INT_MIN;
int main(){
	int n;
	cin>>n;
	for (int i=1;i
		cin>a[i];
		dp[i]=a[i];
	}	
	for (int i=1;i
		for (int j=1;j
			if (a[j]
				dp[i]=max(dp[i],dp[j]+a[i]);
			}
		}
		ans=max(ans,dp[i]);
	}
	coutt_k(1\le i\le k) 
       
      
    >tk​(1≤i≤k)。 

你的任务是,已知所有 n n n 位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入格式

共二行。

第一行是一个整数 n n n( 2 ≤ n ≤ 100 2\le n\le100 2≤n≤100),表示同学的总数。

第二行有 n n n 个整数,用空格分隔,第 i i i 个整数 t i t_i ti​( 130 ≤ t i ≤ 230 130\le t_i\le230 130≤ti​≤230)是第 i i i 位同学的身高(厘米)。

输出格式

一个整数,最少需要几位同学出列。

样例 #1

样例输入 #1

8
186 186 150 200 160 130 197 220

样例输出 #1

4

提示

对于 50 % 50\% 50% 的数据,保证有 n ≤ 20 n \le 20 n≤20。

对于全部的数据,保证有 n ≤ 100 n \le 100 n≤100。

该题实际上就是前面求一个最长上升子序列,对后面求一个最长下降子序列。但是问题在于这两个序列的连接点我们不知道,没有办法直接求解出来,也就是说任意一个点都有可能作为这个连接点,所以我们需要先枚举这个连接点x,再分别对区间[1,x]求最长上升子序列,对区间[x+1,n]求最长下降子序列。这种做法的时间复杂度为O(n3),但是该题的数据范围改为n cin>n; for (int i=1;i cin>a[i]; dp1[i]=1; dp2[i]=1; } for (int i=1;i for (int j=1;j if (a[j] dp1[i]=max(dp1[i],dp1[j]+1); } } } for (int i=n;i=1;i--){ for (int j=n;ji;j--){ if (a[i]a[j]){ dp2[i]=max(dp2[i],dp2[j]+1); } } } for (int i=n;i>=1;i--){ minn=min(n-dp1[i]-dp2[i],minn); } cout string a,b; cina>>b; dp[0][0]=0; for (int i=1;i for (int j=1;j if (a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } cout string a,b; cinab; dp[0][0]=0; for (int i=1;i for (int j=1;j if (a[i-1]==b[j-1]){ dp[i][j]=dp[i-1][j-1]+1; } maxn=max(dp[i][j],maxn); } } cout

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]