2525 小b的字符串
给定一个由 ABCABC 三种字符构成的字符串,问最少改动多少个位置的字符,
使得最终的字符串满足任意两个相邻的字符都不同。
字符串长度 ≤106≤106
输入
一行一个字符串。输出
一行一个整数表示答案。输入样例
ABCBA输出样例
0
思路:
这题怎么搞都能过,dp状态设为选或者不选,或者设为A\B\C三种都行,因为
两两不同有高达6中方案,所以选或者不选的dp方案没有后效性。
模拟的话就是找连续的相同字母,并在每一段相同字母区间上更新答案。
第二种dp代码实现
(写的略复杂,有题解用str[i]-'A'代替了无数分支):
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<set>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=4e5+100;
int dp[N][3];
int main(){
string str;
int len;
while(cin>>str){
memset(dp,INF,sizeof(dp));
len=str.length();
if(str[0]=='A'){
dp[0][0]=0;
dp[0][1]=dp[0][2]=1;
}else if(str[0]=='B'){
dp[0][1]=0;
dp[0][0]=dp[0][2]=1;
}else{
dp[0][2]=0;
dp[0][1]=dp[0][0]=1;
}
for(int i=1;i<len;i++){
if(str[i]=='A'){
dp[i][0]=min(dp[i-1][1],dp[i-1][2]);
dp[i][1]=min(dp[i-1][0],dp[i-1][2])+1;
dp[i][2]=min(dp[i-1][0],dp[i-1][1])+1;
}else if(str[i]=='B'){
dp[i][0]=min(dp[i-1][1],dp[i-1][2])+1;
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
dp[i][2]=min(dp[i-1][0],dp[i-1][1])+1;
}else{
dp[i][0]=min(dp[i-1][1],dp[i-1][2])+1;
dp[i][1]=min(dp[i-1][0],dp[i-1][2])+1;
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
}
}
cout<<min(min(dp[len-1][0],dp[len-1][1]),dp[len-1][2])<<endl;
}
return 0;
}
THE END;