线性dp

最抽象的一个dp,出的题跟它八竿子打不着关系
简单来讲,就是外层循环从1到n遍历一遍,内层循环更新维护1到n-1的最大值
下降的话就从n到1遍历,更新维护n-1到1
1.最长上升序列

没什么好说的
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
int f[maxn];
int b[maxn]; 
int vis[maxn];
int cnt=0,len=0,last=0;
void print(int n){
	if(n==0) return;
	print(vis[n]);
	cout<<b[n]<<" ";
}
int main(){
//	freopen("a1.txt","r",stdin);
	int a1;
	while(cin>>a1){b[++cnt]=a1;}
	for(int i=1;i<=cnt;i++){
		f[i]=1;
		for(int j=1;j<=i-1;j++){
			if(b[j]<b[i]){
				f[i]=max(f[i],f[j]+1);
				if(f[i]==f[j]+1)
				vis[i]=j;
			}
		}
		len=max(len,f[i]);
		if(len==f[i]){
			last=i;
		}
	}
	cout<<"max="<<len<<endl;
	print(last);
}
但是由于本题的spj,我们发现了点好玩的

image
我把对应的数输出成了对应的下标,但还是过了,后面证明,这个spj仅是判断你的长度是否正确以及这个序列是否是上升序列
,然后没了,后面我们他序列递增的数改为随机数,这个程序就变成了rp检测机,(以下的图是同一个程序)
image

2.合唱队型
还是遍历每一个点,分别从左到右和从右到左遍历最长上升/下降队列,由于遍历更新时包括了这个点,所以要在求长度时-1;
3.拦截导弹
最多能拦截的导弹数就是求最长下降序列,要拦截所有导弹最少要配备的系统数就是求最长上升序列
要拦截所有导弹最少要配备的系统数就是多一个导弹比目前拦截范围大就多一套系统
挖地雷,麻烦的聚餐,最长公子串长度等有时间再写,奶牛渡河也写一下

posted @ 2024-02-17 21:33  shaoyufei  阅读(27)  评论(0)    收藏  举报