动态规划——试剂稀释

题目描述

一种药剂可以被稀释成不同的浓度供病人使用,且只能稀释不能增加浓度;又已知医院规定同一瓶药剂只能给某个病人以及排在他后面的若干人使用。现为了能最大限度利用每一瓶药剂(不考虑每一瓶容量),在给出的一个病人用药浓度序列(病人的顺序不能改变)中找出能同时使用一瓶药剂的最多人数。

关于输入

有两行,第一行是一个整数n,为病人的人数,假设不超过100;第二行为一个浮点数(double)序列,为每个病人的用药浓度,浮点数之间用一个空格隔开。

关于输出

输出一行,该行包含一个整数,为所求的最大人数。

例子输入

6
0.7 0.9 0.6 0.8 0.8 0.4

例子输出

4

优化算法(以找Longest Increasing Subsequence为例)

定义low(i),表示长度为i的LIS中结尾元素的最小值

对于LIS_1, LIS_2,如果LIS_1结尾元素小于LIS_2结尾元素,则能拼接到LIS_2的数一定能拼接到LIS_1,因此我们只需要维护结尾元素的最小值即可。

对于每一个数A[i] :

        如果A[ i ] > low[当前最长的LIS长度],就把 A[ i ]接到当前最长的LIS后面,即low[当前最长的LIS长度+1] = A[ i ]

        否则,用 A[ i ] 更新 low 数组:在low数组中找到第一个大于等于A[ i ]的元素low [ j ],令low [ j ] = A[ i ]。

        由于low是单调递增的,可以进行二分查找

时间复杂度:O(NlogN)

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
	int n;
	double a[100] = {};
	double high[100] = {};
	int ans = 1;//初始时LDS长度为1
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		high[i] = 99999;
	}
	high[1] = a[1];
	for (int i = 2; i <= n; ++i) {
		if (a[i] <= high[ans])//若a[i]<high[ans],直接把a[i]接到后面
			high[++ans] = a[i];
		else//否则,找到high中第一个<=a[i]的位置high[j],用a[i]更新high[j]
		{
			for (int j = 1; j <= n; ++j) {
				if (high[j] < a[i]) {
					high[j] = a[i];
					break;
				}
			}
		}
	}
	cout << ans << endl;
	return 0;
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值