逛画廊的一种解法

是参考了别人的代码学习的一种解法,总体思路是贪心算法,用一个不断更新的动态区间去找到最优解,当遍历完所有的画,最终确立的区间就是最优区间

这个区间的要求是要至少有每一位大师的一幅画,根据这个原则确定区间的边界,因此再开一个数组,记录当前区间包含的每位大师的画数,每位大师的画数>=1,判断不需要遍历当前这个数组来判断是否满足要求。

而是看更新完端点后,当前端点的画对应的大师编号,看这个大师的画数是否>=1,因为这个区间满足至少有每一位大师的一幅画这个条件,而改变区间端点只有当前端点的画对应的大师编号的画数变化,这样优化了判断条件

代码如下:

#include<stdio.h>
int b[2001];
int a[1000010];
//定义全局变量这样数组元素初始值为0
int main()
{
    int num = 0;
    int r = 0, l = 1, n, m, ansl, ansr;
    scanf("%d%d", &n, &m);
    for (int j = 1; j <= n; j++)
        scanf("%d", &a[j]);
    int i = 1;
    while (num != m)
    {
        if (b[a[i]] == 0)num++;
        //左端点初始值为0,不断更新右端点,直到覆盖所有画师的画,也就是num==m
        b[a[i]]++;
        r++;
        i++;
    }
    //开始缩小区间,只要对应画师的画数大于1就可以保证看完所有的画
    while (b[a[l]] > 1)
        b[a[l++]]--;
    ansl = l; ansr = r;
    //当且仅当这个区间才可以满足看完所有画师的话,循环结束
    //上面的步骤相当于给这个最小的区间赋一个初值,下面开始不断优化区间
    while (i < n)
    {
        //遍历右边的画让画师对应的画数增加,因此又可以移动左边的区间端点
        b[a[i]]++;
        r++;
        i++;
        while (b[a[l]] > 1)
            b[a[l++]]--;
        //如果现在的区间更好,那么就更新答案区间,直到遍历完全部画,得到最优区间
        if (ansr - ansl > r - l)
        {
            ansr = r;
            ansl = l;
        }
    }
    printf("%d %d", ansl, ansr);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值