牛妹爱数列

D-牛妹爱数列_牛客练习赛67 (nowcoder.com)

问题描述:给01数组,可以进行一下两种操作:

  1. 将位置上的数进行翻转
  2. 将从1到当前位置的数进行翻转

求最小的翻转次数,使数列上的数全部变为0。

思路:

最优,满足最优子结构,无后效性,子问题重叠,用dp。

找状态:从1到当前位置 全0/1时的最小花销。

转移方程:

ai = 1
F ( i , 0 ) = m i n ( F ( i − 1 , 0 ) + 1 , F ( i − 1 , 1 ) + 1 ) F ( i , 1 ) = m i n ( F ( i − 1 , 0 ) + 1 , F ( i − 1 , 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)) F(i,0)=min(F(i1,0)+1,F(i1,1)+1)F(i,1)=min(F(i1,0)+1,F(i1,1))
ai = 0
F ( i , 0 ) = m i n ( F ( i − 1 , 0 ) , F ( i − 1 , 1 ) + 1 ) F ( i , 1 ) = m i n ( F ( i − 1 , 0 ) + 1 , F ( i − 1 , 1 ) + 1 ) F(i,0) = min(F(i-1,0), F(i-1,1)+1) \\ F(i,1) = min(F(i-1,0)+1, F(i-1,1)+1) F(i,0)=min(F(i1,0),F(i1,1)+1)F(i,1)=min(F(i1,0)+1,F(i1,1)+1)
状态表示:

F(i,j)表示从1到当前位置全转为j的最小花销。

目标:
F ( N , 0 ) F(N,0) F(N,0)
边界:无。

代码:

int f[N][2];
void inpfile();
void solve() {
    int n; cin>>n;
    rep(i,1,n) {
        int v; cin>>v;
        if(v) {
            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]);
        } else {
            f[i][0] = min(f[i-1][0], f[i-1][1] + 1);
            f[i][1] = min(f[i-1][0] + 1, f[i-1][1] + 1);
        }
    }
    cout<<f[n][0];
}

你可能感兴趣的:(算法题,算法)