题目描述
给一个只包含-1,0,1的数列,每次操作可以让a[i]+=a[i-1],求最少操作次数使得序列单调不降
输入格式
第一行 : n n n
第二行: a 1 , a 2 , ⋯ , a n a_1, a_2, \cdots, a_n a1,a2,⋯,an
输出格式
最少的操作次数
输入输出样例
输入 #1
6
-1 1 0 -1 0 1
输出 #1
3
题解
- 首先我们可以发现一个性质,进行最优操作后的数还是
−
1
,
0
,
1
-1,0,1
−1,0,1
显然 - 方程的话看代码理解下拿
懒得打了
code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 100;
const int inf = 0x3f3f3f3f;
template <class T>
inline void read(T &s) {
s = 0; T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
s *= w;
}
int n;
int a[maxn];
int f[maxn][5];
int main() {
freopen("data.in", "r", stdin);
freopen("2.out", "w", stdout);
read(n);
for (int i = 1; i <= n; ++i) read(a[i]);
memset(f, 0x3f, sizeof(f));
f[1][a[1] + 1] = 0;
for (int i = 2; i <= n; ++i) {
if (a[i] == 1) {
f[i][0] = f[i - 1][0] + 2;
f[i][1] = f[i - 1][0] + 1;
f[i][2] = min(f[i - 1][0], min(f[i - 1][1], f[i - 1][2]));
}
else if (a[i] == 0) {
f[i][0] = f[i - 1][0] + 1;
f[i][1] = min(f[i - 1][0], f[i - 1][1]);
f[i][2] = f[i - 1][2] + 1;
}
else {
f[i][0] = f[i - 1][0];
f[i][2] = f[i - 1][2] + 2;
}
}
int ret = 0x3f3f3f3f;
ret = min(f[n][0], min(f[n][1], f[n][2]));
if (ret == inf) puts("BRAK");
else printf("%d\n", ret);
return 0;
}