• POJ 3320 Jessica's Reading Problem ( 尺取法 )


    题意 : 给你一本书、整本书有若干个不同的知识点,书的每一页都包含了一个知识点 ( 包含的知识点可能与其他页重复 ),问你如果取连续的几页用来读完书中包含的所有知识点,那么这连续的几页最少是多少?( 书的页数 ≤ 1e6 )

    分析 : 最直接的想法就是先 O(n) 地枚举页首,然后计算贡献,在过程中维护最小值即可。但是这样做最差的情况就可能达到 O(n^2) 因此需要优化。那现在来考虑一下如果当前枚举到 st 且符合条件的页尾为 en ,那么其贡献就是 en - st + 1,接下来枚举 st+1 的时候会发现其符合条件的页尾 (令为 en') 必定不小于 en,即 en' ≥ en。道理应该不难理解,因为如果当前从 st 到 st+1 则自然少了 st 这一页包含的知识点,而 st 这一页作为页首符合条件的页尾都要达到 en ,那么少了一个知识点的 st+1 作为页首作为符合条件的相应页尾必然不小于 en ,因此此题使用尺取法可行!具体实现就看代码吧!

    #include<stdio.h>
    #include<map>
    #include<set>
    using namespace std;
    const int maxn = 1e6 + 10;
    int Page[maxn], num[maxn];
    set<int> Have;
    map<int, int> mp;
    int tot;
    int main(void)
    {
        int n;
        while(~scanf("%d", &n)){
    
            mp.clear();
            tot = 1;
            for(int i=1; i<=n; i++){
                num[i] = 0;
                scanf("%d", &Page[i]);
                if(!mp.count(Page[i]))
                    mp[Page[i]] = tot++;
            }
    
            int L, R, ans;
            L = R = 1;
            ans = n;
    
            Have.clear();
            Have.insert(mp[Page[L]]);
            num[mp[Page[L]]]++;
            while(L <= R && R <= n){
                if((int)Have.size() == tot-1){
                    ans = min(ans, R-L+1);
                    if(--num[mp[Page[L]]] == 0)
                        Have.erase(mp[Page[L]]);
                    L++;
                }else{
                    R++;
                    Have.insert(mp[Page[R]]);
                    num[mp[Page[R]]]++;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    服务器 防Dos攻击
    多浏览器 div 半透明
    网站工具收集
    广告平台
    ie6 position:fixed
    数据图 饼图 曲线图
    36个css框架
    css3 特效
    日ip 日pv
    网站 需求分析 收集
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8037143.html
Copyright © 2020-2023  润新知