重启系统(等级考试4级 2021-03 T4)
这道题如果没有一次重启系统的机会就相当于两个最长不下降子序列加在一起。
所以只需要改亿点点即可
把dp分为 dpleft 和 dpright
最长不下降子序列程序:最长上升子序列 II 时间复杂度(nlogn) - 王浩泽 - 博客园 (cnblogs.com)
#include<bits/stdc++.h>using namespace std;const int N=1e5;const int inf=1e9;int main(){ int a[N],dp[N],n; cin>>n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); int len=0; for(int i=1;i<=n;i++) { int l=0,r=len+1; while(l+1!=r) { int m=l+r>>1; if(dp[m]<a[i]) { l=m; } else { r=m; } } dp[r]=a[i]; len=max(len,r); } cout<<len; return 0;}
合在一起即可(还要注意亿点细节)
like
for(int x = 1; x <= n; x++){ ans = max(ans, dpleft[x] + dpright[x + 1]); }
这里的dpleft[x]应该加上dpright[x+1] 如果用x 和 x 的话 x可能会被用两次。
dpleft 和 dpright 都应该初始化为1
在这里给大家推荐一个函数让后面原来倒着算的最长下降子序列 变成正着算的最长上升子序列。
reverse(a + 1, a + n + 1);
之后再拼拼凑凑变成前一段程序:
scanf("%d",&n); for (int i = 1;i <= n;i++){ scanf("%d",&a[i]); dpright[i] = dpleft[i] = 1; } reverse(a + 1, a + n + 1); for (int i = 1;i <= n;i++){ for (int j = 1; j < i;j++){ if(a[i] >= a[j]){ dpleft[i] = max(dpleft[i],dpleft[j] +1); } } } for (int i = 2;i <= n;i++){ dpleft[i] = max(dpleft[i - 1], dpleft[i]); } for(int i = n - 1; i >= 1; i--){ for(int j = n; j > i; j--){ if(a[i] <= a[j]){ dpright[i] = max(dpright[i], dpright[j] + 1); } } }
最后再找亿下最大值塞入ans中最后输出即可:
for(int i = n - 1; i >= 1; i--){ dpright[i] = max(dpright[i], dpright[i + 1]); } int ans = 0; for(int x = 1; x <= n; x++){ ans = max(ans, dpleft[x] + dpright[x + 1]); } printf("%d\n", ans); return 0;
完整代码:
#include <bits/stdc++.h> using namespace std; int dpleft[10005],dpright[10005], a[10005]; int n; int main(){ scanf("%d",&n); for (int i = 1;i <= n;i++){ scanf("%d",&a[i]); dpright[i] = dpleft[i] = 1; } reverse(a + 1, a + n + 1); for (int i = 1;i <= n;i++){ for (int j = 1; j < i;j++){ if(a[i] >= a[j]){ dpleft[i] = max(dpleft[i],dpleft[j] +1); } } } for (int i = 2;i <= n;i++){ dpleft[i] = max(dpleft[i - 1], dpleft[i]); } for(int i = n - 1; i >= 1; i--){ for(int j = n; j > i; j--){ if(a[i] <= a[j]){ dpright[i] = max(dpright[i], dpright[j] + 1); } } } for(int i = n - 1; i >= 1; i--){ dpright[i] = max(dpright[i], dpright[i + 1]); } int ans = 0; for(int x = 1; x <= n; x++){ ans = max(ans, dpleft[x] + dpright[x + 1]); } printf("%d\n", ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通