牛客 牛妹爱数列 ###K ###K //K
题目链接:https://ac.nowcoder.com/acm/problem/205087
思路: 刚开始考虑的是贪心,让sum=0 遇到1就++ 0则-- 找到sum最大的时候,在这个时候反转一次, 这样是会漏情况的 如 0 0 0 0 0 1 1 1 可以把0变为1 再全部变为0
那么只能考虑dp了 首先要确定dp的意义,根据要求的 肯定是要dp[n]为前n为都为0的 ,那么考虑把dp[i]定为 前i位都位0的最少操作数, 再考虑转移,
假设当前为1 可以由前一位都是0的转移而来 在+1, 也可以由前面全为1的翻转一次直接得来,所以就需要把前i位全为1的操作数也记录下来,那么就开二维dp
dp[i][1] dp[i][0] 表示前i位全为0/1 的最小操作数 注意初始化即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =1e5+10; 6 const int mod=1e9+7; 7 int a[maxn]; 8 9 int dp[maxn][2]; 10 11 12 13 int main() 14 { 15 ios::sync_with_stdio(false); 16 cin.tie(0); 17 int n; 18 cin>>n; 19 for(int i=1;i<=n;i++) 20 { 21 cin>>a[i]; 22 } 23 for(int i=1;i<=n;i++) 24 { 25 for(int j=0;j<2;j++) 26 dp[i][j]=1e9; 27 } 28 dp[0][0]=dp[0][1]=0; 29 for(int i=1;i<=n;i++) 30 { 31 if(a[i]) 32 { 33 dp[i][1]=min(dp[i-1][1],dp[i-1][0]+1); 34 dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+1); 35 } 36 else 37 { 38 dp[i][0]=min(dp[i-1][0],dp[i-1][1]+1); 39 dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+1); 40 } 41 } 42 cout<<dp[n][0]<<'\n'; 43 44 45 46 47 48 49 }

浙公网安备 33010602011771号