Greedy:Jessica's Reading Problem(POJ 3320)

                

            Jessica's Reading Problem

  题目大意:Jessica期末考试临时抱佛脚想读一本书把知识点掌握,但是知识点很多,而且很多都是重复的,她想读最少的连续的页数把知识点全部掌握(知识点都在书上,每一页都是一个知识点)

  这一题可以用3061的游标卡尺法,我们可以先数数书上倒到底有多少个知识点,因为知识点都是序数,我们可以用二分法直接找到O(PlogP),这里可以采用set模板直接偷懒了,然后我们就可以用游标卡尺法了,因为所有知识点都要出现一次,所以我们统计新的知识点的出现就好了,最后我们找最短的那个连续就好。

  

 1 #include <iostream>
 2 #include <functional>
 3 #include <algorithm>
 4 #include <map>
 5 #include <set>
 6 
 7 using namespace std;
 8 
 9 static int books[1000001];
10 
11 void solve(const int);
12 
13 int main(void)
14 {
15     int pages;
16     while (~scanf("%d", &pages))
17     {
18         for (int i = 0; i < pages; i++)
19             scanf("%d", &books[i]);
20         solve(pages);
21     }
22     return 0;
23 }
24 
25 void solve(const int pages)
26 {
27     int ideas_size, s = 0, t = 0, ans, nums = 0;//游标卡尺法标准形式
28     static set<int>ideas;
29     static map<int, int>index;//把ideas和index放函数里面初始化能省几十ms
30 
31     for (int i = 0; i < pages; i++)
32         ideas.insert(books[i]);
33     ideas_size = ideas.size();
34     ans = pages;//ans千万不要初始化成答案个数了,之前在这里初始化错了导致wa
35 
36     while (1)
37     {
38         while (t < pages && nums < ideas_size)
39         {
40             if (index[books[t++]]++ == 0)//找不到这个元素,则一定在尾端
41                 nums++;
42         }
43         if (nums < ideas_size)//因为知识点的个数一定是符合条件的,所以这里直接作为跳出条件就可以了
44             break;
45         ans = min(ans, t - s);
46         if (--index[books[s++]] == 0)
47             nums--;
48     }
49     printf("%d
", ans);
50 }

  

  因为使用模板的,所以速度会慢一点

原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5149964.html