ACM模板笔记:最长不下降/上升子序列,最长公共子序列(DP)
作者:互联网
这只是我个人的备忘录,没有详细的注解,想了解原理的请去找其他的贴子 ,如果你能看得懂就将就看:P
淦宁佬,能拿到蓝桥杯省二就算成功:(,ACM拿锤子奖,我这说唱专业的说唱学生百分百白给,是这样的
求最长不上升子序列
-1s算法
int maxr = 0;
for (int i = counter; i >= 1; i--) {
dp[i] = 1;
for (int j = i + 1; j <= counter; j++) {
if (datas[j] <= datas[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
maxr = max(maxr, dp[i]);
}
cout << maxr << endl;
nlogn算法(在做了,在做了)
求最长不下降子序列
-1s算法
int ans2 = 0;
for (int i = 1; i <= counter; i++) {
dp2[i] = 1;
for (int j = 1; j < i; j++) {
if (datas[j] < datas[i])
dp2[i] = max(dp2[i], dp2[j] + 1);
}
ans2 = max(ans2, dp2[i]);
}
cout << ans2;
nlogn算法(在做了,在做了)
最长公共子序列
-1s做法
for(int i=1;i<=n;i++)
{
dp[i]=1;//初始化
for(int j=1;j<i;j++)//枚举i之前的每一个j
if(data[j]<data[i] && dp[i]<dp[j]+1)
//用if判断是否可以拼凑成上升子序列,
//并且判断当前状态是否优于之前枚举
//过的所有状态,如果是,则↓
dp[i]=dp[j]+1;//更新最优状态
}
nlogn做法
for(int i=1;i<=n;i++){
int l=0,r=len,mid;
if(map[b[i]]>f[len])f[++len]=map[b[i]];
else {
while(l<r){
mid=(l+r)/2;
if(f[mid]>map[b[i]])r=mid;
else l=mid+1;
}
f[l]=min(map[b[i]],f[l]);
}
}
这玩意也可以离散化(来自洛谷)
int n,a[100005];
int ans,ma,c[100005],b[100005],r[100005];
//二分
int fen(int x){
int le=0,ri=ma,mid;
while(le<ri){
mid=(le+ri)/2+1;
if(r[mid]>=x) ri=mid-1;
else le=mid;
}
return le;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],c[a[i]]=i;
for(int i=1;i<=n;i++){
int x;
cin>>x;
b[i]=c[x];//这里做离散化
}
//然后就用普通的n^2
int maxr = 0;
for (int i = n; i >= 1; i--) {
r[i] = 1;
for (int j = i + 1; j <= n; j++) {
if (b[j] <= b[i]) {
r[i] = max(r[i], r[j] + 1);
}
}
maxr = max(maxr, r[i]);
}
cout << maxr << endl;
cout<<ans;
return 0;
}
标签:le,int,max,mid,ACM,maxr,序列,最长,dp 来源: https://blog.csdn.net/qq_46207392/article/details/114751940