线性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;
}
=