题目
http://oj.daimayuan.top/course/10/problem/703
思路
差分数组出来后,就变成了合并相邻项。
dp做。
令 f[i][t] = x 代表原差分数组第 i 项往左合并合并到和为 t 时,到第几项。
t因为范围较大,开个map。
总的时间复杂度 n*log(*log ?)。
代码
// http://oj.daimayuan.top/course/10/problem/703
#include <bits/stdc++.h>
using namespace std;
#define MAXN 300005
int n;
int a[MAXN], b[MAXN];
map<int, int> f[MAXN];
int ans[MAXN];
void upd(int &x, int y) {x=min(x, y);}
void solve()
{
scanf("%d",&n);
for (int i=1; i<=n; i++) {
scanf("%d",&b[i]);
}
for (int i=1; i<n; i++) {
a[i]=b[i+1]-b[i];
f[i].clear();
f[i][a[i]]=i-1;
}
for (int i=1; i<n; i++) {
int pos=i-1;
int val=a[i];
ans[i]=ans[i-1]+1;
while (pos && f[pos].find(val)!=f[pos].end()) {
pos=f[pos][val];
upd(ans[i], ans[pos]+1);
val+=val;
f[i][val]=pos;
}
}
printf("%d\n", ans[n-1]+1);
}
int main()
{
int ttt;
scanf("%d",&ttt);
while (ttt--) {
solve();
}
return 0;
}