线性dp-牛妹爱数列

牛客-牛妹爱数列

原题链接:传送门

题目大意

有一个长度为n的序列a,保证它是一个01序列,并执行以下两种操作:

1.单点修改:将位置x上的数翻转(0变1,1变0);

2.前缀修改:将位置1~x上的数翻转(每个数都0变1,1变0)。

他现在想要最小化翻转次数,使得数列上的所有数都变为0。

数据保证\(1\le n\le 10^5,0\le a_i\le 1\)

分析

首先我们大致判断这个一个dp,通过观察此题应该是一个线性dp

通过观察数据范围我么可以推断出状态大致应该是f(n , c) / f(n) 维度的状态表示

其中c为一个常数。

状态表示

f(i , 0/1) 表示前i位修改位全部为 0 / 1 的最小消耗代价

状态计算

AC 代码

C++ code

void slove()
{
	int n;cin >> n;
	vector<int> a(n + 1);

	for(int i = 1;i <= n ;i ++)cin >> a[i];

	for(int i = 1;i <= n ;i ++)
	{
		if(a[i] == 0)
		{
			f[i][0] = min(f[i-1][0] , f[i-1][1] + 1);
			f[i][1] = min(f[i-1][1] + 1,f[i-1][0] + 1);
		}
		if(a[i] == 1)
		{
			f[i][0] = min(f[i-1][0] + 1, f[i-1][1] + 1);
			f[i][1] = min(f[i-1][0] + 1, f[i-1][1]);
		}	
	}
	cout << min(f[n][0] , f[n][1] + 1) << endl;
}

=

posted @ 2020-08-30 20:21  _starsky  阅读(153)  评论(0编辑  收藏  举报