【10-24模拟赛T1】Alice 和璀璨花

著名的植物学家 Alice 经过多年的探索,终于找到了传说中的璀璨花。璀璨花的生长速度非常迅猛,如果不加以合适的控制,璀璨花会因为过度内耗而死亡。璀璨花的生长趋势可以用序列 a 表示,Alice 在研读前人对璀璨花的研究后总结出了一个控制序列 b。Alice 需要让璀璨花的生长趋势尽可能贴合控制序列,这样璀璨花就能尽可能快且安全地生长,以让更多人能欣赏到传说花卉的美。

Alice 可以通过基因编辑技术让 a 的任意子序列 a 成为璀璨花的生长趋势,设 a 的长度为 n,若 i[1,n1],ai+1>biai,那么璀璨花的培育趋势就是安全的。另外,越长的生长趋势能让成熟的璀璨花更美,所以 Alice 想知道可能的最长的璀璨花生长趋势子序列的长度。

dpi,j 表示前 i 个数中选 j 个数的最小结尾,可以得出转移方程:

  • ai>dpi1,j1bj1,那么 dpi,j=min(ai,dpi1,j)

  • aidpi1,j1bj1,那么 dpi,j=dpi1,j

显然可以用滚动数组压掉一维。

但转移还是 O(n2) 的,考虑到 dpi1 是单调不减的,我们 lower_bound 一个位置 p,满足 dpi1,p1<aidpi1,pai
,发现 j[1,p],dpi,j=dpi1,j(因为 dpi1,j<ai),j[p+1,n],dpi,j=dpi1,j(因为 dpi,j1 已经大于 ai 了,那么 dpi,j1bj1 肯定大于 ai)。

最后总复杂度 O(nlogn)

//不开 long long 见祖宗
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 9,INF = 0x7f7f7f7f7f7f7f7f;
int n;
int a[N],b[N];
int dp[N];
signed main(){
	//freopen("alice.in","r",stdin);
	//freopen("alice.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];
	for(int i = 1;i <= n;i++)
		cin >> b[i];
	memset(dp,0x7f,sizeof dp);
	dp[0] = 0;
	for(int i = 1;i <= n;i++){
		int pos = lower_bound(dp + 1,dp + n + 1,a[i]) - dp;
		if(a[i] > dp[pos - 1] * b[pos - 1])
			dp[pos] = min(dp[pos],a[i]);
	}
	for(int ans = n;ans >= 1;ans--)
		if(dp[ans] != INF){
			cout << ans;
			break;
		}
	return 0;
}
posted @   5t0_0r2  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示