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 }