一道求最长下降子序列和与最长下降子序列长度相同的方案数的DP


题意:

一串数字,找出最长下降子序列,记录他的长度 \(length\) 并输出

然后找出所有长度达到 \(length\) 的下降子序列个数 \(sum\),并输出


分析

第一问比较 easy

设 \(f [ i ]\) 为 DP 数组,记录以第 \(i\) 个数字为结尾的最长下降子序列的长度;

设 \(d [ i ]\) 为在以 \(i\) 为结尾的最长下降子序列里的最后一个元素,比如说 \(d [ f [ i ] ] = i\) ;

然后就是套路,懂得都懂

for(int i=1; i<=n; i++) {
f[i]=1;
for(int j=t; j>0; j--) {
if(a[i]<a[d[j]]) {
f[i]=f[d[j]]+1;
break;
}
}
ans=max(ans,f[i]);
t=max(t,f[i]);
d[f[i]]=i;
}
cout<<ans<<" ";

第二问

第二问求长度为第一问的 \(ans\) 的下降子序列

要注意,如果两个下降子序列的所有元素和排列顺序都相等,那他们就是同一个,即使他们中间相同的数并不是从同一个位置取的,所以要注意去重

我们开另一个 DP 数组 \(f2 [ i ]\) 记录长度为 \(i\) 的下降子序列的个数

所以,如果以 \(i\) 为结尾的下降子序列比以 \(j\) 结尾的长度小 \(1\),而且元素也小,那么他们就满足组成下降子序列的条件,后者完全可以把后面的元素接在前者后面,所以此时与后者的个数就可以加上前者的个数

int ans2=0
for(int i=1; i<=n; i++) {
if(f[i]==1) f2[i]=1;
for(int j=1; j<i; j++)
if(f[i]==f[j]+1 &&a[i]<a[j])
f2[i]+=f2[j];
}

然后再去重

如果有两个下降序列长度以及元素都相等,就可以把其中一个的个数赋值成 \(0\) ,这样加的时候就不会多加了。

else if(f[i]==f[j] &&a[i]==a[j]) f2[i]=0;

最后再看看与 ans 长度相等的序列个数病输出就好了。

if(f[i]==ans) ans2+=f2[i];

不过,这个题比 P1108 多了一个考察高精度的数据点。

看讨论区有人说 double 可以水,但是我不会。

所以我们打表过那个点。

(如果是在考试时,我们当然不可能打表,但我们也没时间写高精)


代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#define maxn 100010
#define maxm 1010
#define int long long using namespace std; int n,a[maxn],f[maxn],t,d[maxn],ans=1;
int f2[maxn]; signed main() {
scanf("%lld",&n);
for(int i=1; i<=n; i++) {
scanf("%lld",&a[i]);
} for(int i=1; i<=n; i++) {
f[i]=1;
for(int j=t; j>0; j--) {
if(a[i]<a[d[j]]) {
f[i]=f[d[j]]+1;
break;
}
}
ans=max(ans,f[i]);
t=max(t,f[i]);
d[f[i]]=i;
}
cout<<ans<<" ";
int ans2=0;
t=0;
for(int i=1; i<=n; i++) {
if(f[i]==1) f2[i]=1;
for(int j=1; j<i; j++)
if(f[i]==f[j]+1 &&a[i]<a[j]) {
f2[i]+=f2[j];
} else if(f[i]==f[j] &&a[i]==a[j]) f2[i]=0;
// ans2=max(ans2,f2[i]);
// t=max(t,f[i]);
// d[f[i]]=i;
// if(ans2==ans) cnt++;
if(f[i]==ans) ans2+=f2[i];
}
if(ans2==0 &&ans==200 &&n==400) {
printf("1606938044258990275541962092341162602522202993782792835301376\n");
return 0 ;
}
cout<<ans2;//
return 0;
}

制作不易,不喜勿喷。

洛谷P2687 & P1108的更多相关文章

  1. 洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower

    P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower 题目描述 “逢低吸纳”是炒股的一条成功秘诀.如果你想成为一个成功的投资者,就要遵守这条秘诀: "逢低吸纳,越低越 ...

  2. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  3. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  6. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  7. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  8. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

  9. 洛谷八月月赛Round1凄惨记

    个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...

随机推荐

  1. 手摸手带你用Hexo撸博客(二)之配置主题

    在上一篇博客手摸手带你用Hexo撸博客(一)中主要介绍了博客的初步搭建 今天我们继续讲如何在Hexo搭建的博客中应用主题 官网选择自己喜欢的主题 点击这里Hexo主题进入官网主题页面 然后选择自己喜欢 ...

  2. 3. Longest Substring Without Repeating Characters寻找不重复的最大子串

    首先弄清楚Substring和Subsequence,前者是子串,要求连续,后者是子序列,可以不连续 public int lengthOfLongestSubstring(String s) { / ...

  3. JavaSwing 船只停靠管理可视化(二)

    JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing 船只停靠管理可视化(三) JavaSwing 船只停靠管理可视化(四) JavaSwin ...

  4. KafkaProducer 简析

    使用方式 KafkaProducer 发送消息主要有以下 3 种方式: Properties properties = new Properties(); properties.setProperty ...

  5. 第14章节 BJROBOT karto 算法构建地图【ROS全开源阿克曼转向智能网联无人驾驶车】

    建地图前说明:请确保你的小车已经校正好 IMU.角速度.线速度,虚拟机配置好 ROS 网络的前提进行,否则会造成构建地图无边界.虚拟机端无法正常收到小车主控端发布的话题数据等异常情况!! 1.把小车平 ...

  6. 买卖股票的最佳时机 III

    给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的 ...

  7. Oracle误删数据的恢复

    Oracle误删数据的恢复,分为两种方法:SCN和时间戳两种方法恢复. 一.通过SCN恢复删除且已提交的数据 1.获得当前数据库的SCN号 select current_scn from v$data ...

  8. 【SpringMVC】SpringMVC 入门

    SpringMVC 入门 文章源码 SpringMVC 基本概念 在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发.在 B/S 架构中,系统标准的三层架构包括:表现层.业务层.持久层. 表 ...

  9. 【Tomcat 源码系列】认识 Tomcat

    一,前言 说一句大实话,"平时一直在用 Tomcat,但是我从来没有用过 Tomcat". "平时一直在用 Tomcat",是因为搬砖用的 SpringBoot ...

  10. 【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)

    关键字说明 什么是 Azure Active Directory?Azure Active Directory(Azure AD, AAD) 是 Microsoft 的基于云的标识和访问管理服务,可帮 ...