Runoob-ES6:ECMAScript 6 簡明教程
阿新 • • 發佈:2020-08-14
題目連結
https://ac.nowcoder.com/acm/contest/6885/D
題目大意
給定一個長度為 N 的序列 A , 保證它是一個 01 序列 , 並執行以下兩種操作 :
①、單點修改:將位置 X 上的數翻轉( 0 變 1 , 1 變 0)
②、字首修改:將位置 1 ~ X 上的數翻轉(每個數都 0 變 1 , 1 變 0)
問最少需要翻轉多少次,使得數列上所有數都變為 0
解題思路
我們定義 dp[i][0/1] 表示當前第 i 個位置 , 將前 i 個位置全變成 0 / 1 的最少運算元。
如果當前位置上 a[i] = 1,則:
dp[i][0] = min(dp[i - 1][0] + 1 , dp[i - 1][1] + 1) , 我們可以將a[i]單獨翻轉,也可以將這字首1一起翻轉;
dp[i][1] = min(dp[i - 1][1] , dp[i - 1][0] + 1) , 我們可以將字首0翻轉 , 然後把a[i]拼上去。
如果當前位置上a[i] = 0,則:
dp[i][0] = min(dp[i - 1][0] , dp[i - 1][1] + 1) , 我們可以將字首1翻轉 , 然後把a[i]拼上去;
dp[i][1] = min(dp[i - 1][0] + 1 , dp[i - 1][1] + 1) , 我們可以將a[i]單獨翻轉,也可以將這字首0一起翻轉;
答案為 dp[n][0] , 時間複雜度 O(n)。
AC_Code
#include<bits/stdc++.h> usingnamespace std; const int N = 1e5 + 10 , inf = 0x3f3f3f3f; int a[N] , dp[N][2]; signed main() { int n; cin >> n; for(int i = 1 ; i <= n ; i ++) cin >> a[i] , dp[i][0] = dp[i][1] = inf; for(int i = 1 ; i <= n ; i ++) { if(a[i]) { dp[i][0] = min(dp[i - 1][0] + 1 , dp[i - 1][1] + 1); dp[i][1] = min(dp[i - 1][1] , dp[i - 1][0] + 1); } else { dp[i][0] = min(dp[i - 1][0] , dp[i - 1][1] + 1); dp[i][1] = min(dp[i - 1][1] + 1 , dp[i - 1][0] + 1); } } cout << dp[n][0] << '\n'; return 0; }