# bzoj1049: [HAOI2006]数字序列

### 题目链接

bzoj1049: [HAOI2006]数字序列

emmmmm

### 代码

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar(); }
while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar();
return x * f;
}
#define LL long long
#define INF (1e17)
const int maxn = 35007;
int n,dp[maxn];
LL a[maxn],b[maxn],c[maxn],Ans[maxn],sumbe[maxn],sumaf[maxn];
inline int find(int x) {
int l = 1,r = n,ret = 0;
while(l <= r) {
int mid = l + r >> 1;
if(c[mid] <= x)l = mid + 1,ret = mid;
else r = mid - 1;
}
return ret;
}
std::vector<int>vec[maxn];
void solve() {
for(int i = 1;i <= n;++ i)
dp[i] = find(b[i]) + 1,c[dp[i]] = std::min(c[dp[i]],b[i]);
int ans = 0;
for(int i = 1;i <= n;++ i) ans = std::max(ans,dp[i]); b[0] = -INF;
printf("%d\n",n - ans); vec[0].push_back(0);
for(int i = 1;i <= n;++ i) {
int u = dp[i] - 1;
for(int j = 0;j < vec[u].size();++ j) {
int v = vec[u][j];if(b[i] < b[v])continue;
sumbe[v - 1] = sumaf[v - 1] = 0;
for(int k = v;k <= i;++ k) sumbe[k] = abs(b[k] - b[v]),sumaf[k] = abs(b[k] -b[i]);
for(int k = v + 1;k <= i;++ k) sumbe[k] += sumbe[k - 1],sumaf[k] += sumaf[k - 1];
for(int k = v;k <= i;++ k)
Ans[i] = std::min(Ans[i],Ans[v] +  sumbe[k] - sumbe[v] + sumaf[i] - sumaf[k]);
}
vec[dp[i]].push_back(i);
}
printf("%lld\n",Ans[n]);
}
int main() {