洛谷P1638 逛画展 (尺取法)

尺取法的经典题目:

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

游客在购买门票时必须说明两个数字,aa 和 bb,代表他要看展览中的第 aa 幅至第 bb 幅画(包含 a,ba,b)之间的所有图画,而门票的价钱就是一张图画一元。

Sept 希望入场后可以看到所有名师的图画。当然,他想最小化购买门票的价格。

请求出他购买门票时应选择的 a,ba,b,数据保证一定有解。

若存在多组解,输出 aa 最小的那组。

首次了解到有尺取法这个东西,实际上就是双指针维护。用从cnt[i]维护区间每种画的个数,双指针扫描即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 const int N=1e6+10;
 5 int n,m,x,sum,y=1e9,a[N],cnt[N];//用从cnt[i]维护区间每种画的个数 
 6  
 7 signed main(){
 8     cin>>n>>m;
 9     for(int i=1;i<=n;i++) cin>>a[i];
10     int l=1,r=1;//双指针扫描 
11     while(l<=r&&r<=n){ 
12         while(sum<m&&r<=n){//移动右指针 
13             if(!cnt[a[r]]) sum++;
14             cnt[a[r]]++;
15             r++; 
16         }
17         if(sum<m) break;
18         if(r-l<y-x+1) x=l,y=r-1;//更新答案区间
19         //if((r-1)-l+1<y-x+1) x=l,y=r-1; 
20         if(cnt[a[l]]==1) sum--; 
21         cnt[a[l]]--;
22         l++;//移动左指针 
23     }
24     cout<<x<<" "<<y;
25     return 0;
26 }

 

posted @ 2022-04-04 15:11  YHXo  阅读(81)  评论(0编辑  收藏  举报