牛客 牛妹爱数列 ###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 }
View Code

 

posted @ 2020-08-17 18:09  canwinfor  阅读(245)  评论(0)    收藏  举报