洛谷P1638 逛画展(尺取初学)

本文介绍了一种算法,用于帮助参观者在观看画展时,既能覆盖所有大师的作品,又能尽可能地节省购票费用。通过动态调整购票范围,该算法能够在满足观看需求的同时,找到最经济的购票方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博览馆正在展出由世上最佳的 M 位画家所画的图画。

wangjy想到博览馆去看这几位大师的作品。

可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,

a和b,代表他要看展览中的第 a 幅至第 b 幅画(包含 a 和 b)之间的所有图画,而门票

的价钱就是一张图画一元。

为了看到更多名师的画,wangjy希望入场后可以看到所有名师的图画(至少各一张)。

可是他又想节省金钱。。。

作为wangjy的朋友,他请你写一个程序决定他购买门票时的 a 值和 b 值。

输入格式
第一行是 N 和 M,分别代表博览馆内的图画总数及这些图画是由多少位名师的画

所绘画的。

其后的一行包含 N 个数字,它们都介于 1 和 M 之间,代表该位名师的编号。

输出格式
a和 b(a<=b) 由一个空格符所隔开。

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,l,r,z,y,ans;
int a[1000005];
int vis[2050];
int main()
{
	ios::sync_with_stdio(0);
	cin>>n>>m;
	ans=n;z=1;y=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	while(1)
	{
		while(y<n&&cnt<m)//右端点右移
		{
			y++;
			if(vis[a[y]]==0)cnt++;
			vis[a[y]]++;
			
		}
		if(cnt<m)break;//循环跳出条件
		if(ans>y-z)//更新答案
		{
			ans=y-z;
			l=z;r=y;
		}
		
		if(--vis[a[z++]]==0)cnt--;//左端点右移
		
		/*while(l<=r&&cnt==m)
		{
			if(cnt==m&&r-l+1<ans)ans=min(ans,r-l+1);
			vis[a[l]]--;
			if(!vis[a[l]])cnt--;
			l++;
		}*/
	}
	cout<<l<<" "<<r;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值