DNA序列 (各点只出现1次的Dp序)

DNA序列(dna)

题目描述

来自JSSI(Jinkela State Scientific Institute)的科学家们尝试制造一个长度为N并且只包含A的DNA序列,不出意外地失败了。他们得到了一个含有A和B两种部件的序列。现在他们打算对实验结果进行篡改,来得到一个全部是A的序列。篡改的方式有两种:

1 更改某一位上部件的状态(A变成B,B变成A)

2 更改某个前缀内所有部件的状态

两种操作的代价都为1。

你的任务自然是求最小代价。

输入

第一行为N,序列长度。

第二行是一个长度为N且只包含A和B的字符串,表示初始序列。

输出

最小代价。

样例输入

12

AAABBBAAABBB

样例输出

4

数据范围

对于10%的数据,N<=10

对于70%的数据,N<=100000

对于100%的数据,N<=1000000

当一个题目有几种只可能出现1次的操作,而某些操作对后续操作的影响相同,且之后的操作不会对前面影响

便可根据对后续情况影响的状况Dp,乃至D成了贪心

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (1000000+10)
int n;
char s[MAXN];
char turn(const char a)
{
    if (a=='A') return 'B';
    else return 'A';
}
int F[2]={0,1};
int main()
{
    freopen("dna.in","r",stdin);
    freopen("dna.out","w",stdout);
    scanf("%d",&n);
    scanf("%s",s);
    for (int i=n-1;i>=0;i--)
    {
//      cout<<F[0]<<' '<<F[1]<<endl;
        int f0=min(F[0]+(s[i]=='B'),F[1]+1+(s[i]=='B'));
        int f1=min(F[0]+1+(s[i]=='A'),F[1]+(s[i]=='A'));
        F[0]=f0;
        F[1]=f1;    
    }
    cout<<min(F[0],F[1])<<endl;

//  while (1);
    return 0;
}