P3558 [POI2013]BAJ-Bytecomputer(线性DP)

题目描述

给一个只包含-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; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值