P1108 低价购买
https://www.luogu.com.cn/problem/P1108
设 表示以 结尾的最长下降子序列最大长度,和以 结尾、以 为长的不重复子序列方案数。这里的不重复不仅要在结尾为 的集合中不重,而且跟 的也不重复。
首先可以发现, 一定不能从 的 转移过来, 表示 之前第一个等于 的数的下标。原因是 能统计的 也能统计,就会重复了,所以不能从 的转移,也不需要。
同时我们发现,符合要求的子序列的开头数字 一定是 第一次出现的地方。或者说,我们不妨令所有符合要求的子序列的开头数字都要这样,容易发现这个要求不会影响答案。
复制#include <bits/stdc++.h> using namespace std; const int N=5e3+5,V=(1<<16)+5; int n,a[N],f[N],g[N],bk[V]; bool isfi[N]; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; isfi[i]=!bk[a[i]]; bk[a[i]]++; } for(int i=1;i<=n;i++){ f[i]=g[i]=1; for(int j=i-1;j&&a[j]!=a[i];j--){ if(a[j]>a[i]){ if(f[j]+1>f[i]){ f[i]=f[j]+1; g[i]=g[j]; } else if(f[j]+1==f[i])g[i]+=g[j]; } } if(f[i]==1&&!isfi[i])g[i]=0; } int id=0,sum=0; for(int i=1;i<=n;i++){ if(f[id]<f[i])id=i,sum=g[i]; else if(f[id]==f[i])sum+=g[i]; } cout<<f[id]<<' '<<sum; }
upd:现在觉得好naive
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】