试剂稀释
题目描述
一种药剂可以被稀释成不同的浓度供病人使用,且只能稀释不能增加浓度;又已知医院规定同一瓶药剂只能给某个病人以及他后面的若干人使用(这若干人不一定要紧挨着排在一起)。现为了能最大限度利用每一瓶药剂(不考虑每一瓶容量),在给出的一个病人用药浓度队列(病人排队的顺序不能改变)中找出能同时使用一瓶药剂的最多人数。
关于输入
有两行,第一行是一个整数n,为病人的人数,不超过100;第二行为一个用空格分隔的浮点数(double)列,为病人队列中从队首到队尾每个人的用药浓度。
关于输出
输出一行,该行包含一个整数,为所求的最大人数。
例子输入
6 0.7 0.9 0.6 0.8 0.8 0.4
例子输出
4
提示信息
用药浓度为 0.9, 0.8, 0.8, 0.4 的四个人可以使用同一瓶依次稀释的药剂(注意这四个人在原来的队伍中并不紧挨着排在一起)。
解题分析
显然本题要求我们在一列数中寻找一个最长的递减数列,那我们如何才能完成这个操作呢?如果我们从开头开始寻找,那问题就需要用到其他的数据结构,所以我们换一个思路,即从数列的末尾开始找,什么意思?举个例子,在(0.7 0.9 0.6 0.8 0.8 0.4)中,我们从0.4开始,给他一个标记为1,代表这是一个递减数列,只有一个元素就是0.4,然后,我们再从后往前寻找,这时,我们碰到了0.8,而0.8是比0.4要更大的,故我们给0.8的下标为0.4的下标加1,即2。然后,我们再往前,又是0.8,然后我们发现它既大于0.4,也大于等于0.8,我们发现这个元素的后面的小于它的元素的下标最大为2,故我们给他的下标为3,再次往前,0.6,我们发现它大于0.4,给他0.4下标加1,即为2,然后是0.9,它大于0.8,0.8,0.4,0.6这些当中最大的下标是3,所以我们给0.9下标定为3+1=4,然后0.7,同理下标定为2(0.6的下标)+1=3。我们再从这些下标中找出一个最大的下标即可。最终,我们获得了答案4。回顾这个过程,我们发现从后面开始寻找的好处就是,可以找一个最大的递增数列,而这反过来看却使我们找到了一个最大的递减数列。
代码实现
#include <bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
vector<int> count(n,1);
vector<double> nums(n);
for(int i=0;i<n;i++){
cin>>nums[i];
}
for(int i=n-1;i>=0;i--){
for(int j=i+1;j<n;j++){
if(nums[i]>=nums[j]){
count[i]=count[i]<(count[j]+1)?(count[j]+1):count[i];
}
}
}
int max=count[0];
for(int i=1;i<n;i++){
max=max<count[i]?count[i]:max;
}
cout<<max<<endl;
return 0;
}