P1108 低价购买 DP
P1108 低价购买 DP
题意:
给定一个序列, 求最长下降子序列,及不重复的方案数。
题解:
最长下降子序列可以用 O(n^2) 的简单dp来求。
不难发现: 在一个元素互不相同的序列中,不会出现重复方案,因此可以通过dp累计答案(详见代码)。然后考虑去重,发现以x结尾的最长序列, 位置靠后的x的方案会包括位置靠前的x的方案。 因此可以删除最后一个x之前的x,dp后剩下的序列是互异的,因此答案不重复。
代码:
蒟丑
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #define inf 0x3f3f3f3f using namespace std; struct p{ int v=inf, l=0, a=0; }f[5005], lp; int n, ans=0, ans1=0; bool cmp(const p& a, const p& b){return a.l>b.l;} int main(){ scanf("%d", &n);f[0].a=1; for(int i=1; i<=n; i++) scanf("%d", &f[i].v); for(int i=1; i<=n; i++){ for(int j=0; j<i; j++){ if(f[j].v == f[i].v) f[j].v = inf, f[j].l = -inf; else if(f[j].v < f[i].v || f[j].l < f[i].l-1) continue; else if(f[j].l == f[i].l-1) f[i].a += f[j].a; else f[i].l = f[j].l + 1, f[i].a = f[j].a; } } sort(f+1, f+n+1, cmp); int end = 2;while(f[end].l == f[end-1].l) end++; for(int i=1; i<end; i++) ans=f[i].l, ans1 += f[i].a; cout << ans << ' ' << ans1; return 0; }
【推荐】AI 的力量,开发者的翅膀:欢迎使用 AI 原生开发工具 TRAE
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 行业思考:不是前端不行,是只会前端不行
· C#高级GDI+实战:从零开发一个流程图
· 2025年:是时候重新认识System.Text.Json了
· 源码浅析:SpringBoot main方法结束为什么程序不停止
· C#性能优化:为何 x * Math.Sqrt(x) 远胜 Math.Pow(x, 1.5)
· 一款实用的 Visual Studio 发布部署插件,助力提高部署效率!
· 独立开发在线客服系统,我是如何与杀毒软件误报斗智斗勇的
· 换成.NET 9,你的LINQ代码还能快上7倍
· AI 时代,为什么我们还有必要写博客?
· where 1 = 1的作用?会影响性能吗?count(*) 和 count(1)哪个快?