interesting sequence 二分???
算法:
此题一眼看去就像是二分题,其实并不满足二分性质。
假设S为29,从1开始枚举长度为2时,就不满足了,但是最长其实为3.。 1 2 20 10 10 3
正确的算法是用L【i]记录 i 能最多往左扩张长度,R【i】记录i能最多往右扩张的长度。。
/* * HONI, zadatak DVONIZ * Autor: Goran Zuzic * * Sluzbeno rjesenje, trebalo bi dobiti sve bodove. Ukupna slozenost O(n lg n). * */ #include <algorithm> #include <functional> #include <ctime> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <set> #include <vector> #include <string> using namespace std; const int MAXN = 100100; int n, S; int A[MAXN]; int L[MAXN], R[MAXN]; vector<int> Ubaci[MAXN]; int main( void ) { while( scanf("%d %d", &n, &S) != EOF ) { for (int i = 0; i < n; ++i) { scanf("%d", A + i); } int a = 0, b = 0; int suma = 0; while(a < n) { if (b < n && suma+A[b] <= S) { suma += A[b++]; } else { R[a] = b-a; suma -= A[a++]; } } printf("sum = %d\n",suma); a = b = n-1; while (a >= 0) { if (b >= 0 && suma+A[b] <= S) { suma += A[b--]; } else { L[a] = a-b; suma -= A[a--]; } } for (int i = 0; i+1 < n; ++i) { int val = min(L[i], R[i+1]); printf("%d %d %d\n",val,i - val + 1, i); Ubaci[i-val+1].push_back(i); //扩张的起点位置, 到K } multiset<int> PQ; for (int i = 0; i < n; ++i) { while (!PQ.empty() && *PQ.begin() < i) PQ.erase(PQ.begin()); for (vector<int>::iterator it = Ubaci[i].begin(); it != Ubaci[i].end(); ++it) { PQ.insert(*it); printf("i = %d %d\n", i, *it); } Ubaci[i].clear(); if (!PQ.empty()) printf("%d max = %d\n", (*PQ.rbegin() - i + 1) * 2 , *PQ.rbegin()); else printf("0\n"); } } return (0-0); }
posted on 2012-10-07 22:51 more think, more gains 阅读(210) 评论(0) 编辑 收藏 举报