ZOJ 3790 Consecutive Blocks (离散化 + 暴力)

题目链接

虽然是一道暴力的题目,但是思路不好想。刚开始还超时,剪枝了以后1200ms,不知道为什么还是这么慢。

题意:给你n个点,每个点有一种颜色ci,给你至多k次删除操作,每次删除一个点,问最多k次操作后连在一起的点颜色相同的最大长度。

思路:由于ci 最大为10^9, 所以需要首先离散化。然后暴力。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <map>
 6 #include <vector>
 7 #include <algorithm>
 8 #define LL long long
 9 using namespace std;
10 const int maxn = 100000 + 10;
11 vector<int>v[maxn];
12 int c[maxn], ans, n, k;
13 
14 void cal(int x)
15 {
16     int i, sz = v[x].size();
17     int sum, p;
18     if(sz <= ans)
19     return;
20     for(i = 0; i < sz; i++) //暴力枚举开始的连续的一串都为x的数字。
21     {
22         sum = 0;
23         for(p = i; p < sz-1; p++)
24         {
25             if(sum+v[x][p+1]-v[x][p] - 1>k)
26             break;
27             sum += v[x][p+1] - v[x][p] - 1;
28         }
29         sum = v[x][p] - v[x][i] + 1 - sum;
30         ans = max(ans, sum);
31         if(p == sz-1)
32         break;
33     }
34 }
35 int main()
36 {
37     int i, a, cnt;
38     while(~scanf("%d%d", &n, &k))
39     {
40         ans = 1;
41         map<int, int>mp;
42         cnt = 1;
43         for(i = 0; i < n; i++)
44         {
45             scanf("%d", &a);
46             if(mp[a] == 0) mp[a] = cnt++; //离散化 cnt.
47             c[i] = mp[a];
48             v[mp[a]].clear();
49         }
50         for(i = 0; i < n; i++) v[c[i]].push_back(i);
51         for(i = 1; i < cnt; i++)
52         cal(i);
53         printf("%d\n", ans);
54     }
55     return 0;
56 }

 

posted @ 2014-06-21 21:06  水门  阅读(256)  评论(0编辑  收藏  举报