您的位置:首页 > 其它

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

2015-09-02 20:17 330 查看
题目链接:

http://poj.org/problem?id=3320

解题思路:

题目大意:

为了准备考试,Jessica开始读一本很厚的课本。要想通过考试,必须把课本中的所有知识点都掌握。这本书总共有P页,第i本页恰好有一个知识点a[i],(每个知识点都有一个整数编号)。全书中同一个知识点可能会被多次提到,所以她希望通过阅读其中连续的一些页把所有的知识点都覆盖到。给定每页写到的知识点,请求出要阅读的最少页数。

算法思想:

我们假设从某一页s开始阅读,为了覆盖所有的知识点,需要阅读到t。这样的话可以知道如果从s+1开始阅读的话,那么必须阅读到t'>=t页为止。由此这题也可以使用尺取法。

AC代码:

#include <iostream>
#include <cstdio>
#include <map>
#include <set>
using namespace std;

int P;
int a[1000005];

void solve(){
    //计算全部知识点的总数
    set<int> all;
    for(int i = 0; i < P; i++){
        all.insert(a[i]);
    }
    int n = all.size();

    //利用尺取法来求解
    int s = 0,t = 0,num = 0;
    map<int,int> cnt;//知识点->出现次数的映射
    int res = P;
    while(1){
        while(t < P && num < n){
            if(cnt[a[t++]]++ == 0){
                //出现新的知识点
                num++;
            }
        }
        if(num < n)
            break;
        res = min(res,t-s);
        if(--cnt[a[s++]] == 0){
            //某个知识点的出现次数为0了
            num--;
        }
    }
    printf("%d\n",res);
}

int main(){
    while(~scanf("%d",&P)){
        for(int i = 0; i < P; i++)
            scanf("%d",&a[i]);
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: