题意
这里有一个由0或1构成字符串,我们需要通过变换字符(1或0)使字符串中相邻的两个字符互不相等。又知道更改第
位的字符需花费
,求使字符串合法的最小花费?
思路
因为我们我那时要求最小花费,但是此处要考虑两个值。
- 改变字符的操作数量
- 改变每一个字符的花费不同
这时我们通过最小值又不可以直接贪心便可以想到动态规划,这道题变简单了!
状态:表示到了第
个字符,当前字母的状态(1/0)。
转移:若当前这个字符状态为1:
- 当前位置不变
dp[i][1] = dp[i - 1][0];
直接等于上一个字符为0的情况。 - 把当前位置的字符变成0
dp[i][0] = dp[i - 1][1] + i + 1;
(枚举字符串的每一位从0开始)等于上一个字符为0的情况再加上所需的花费。
总代码
#include<bits/stdc++.h>
#define int long long//防止爆int, 本题不用。
using namespace std;
const int MAXX = 1e6 + 5;
string s;
int dp[MAXX][2];
signed main(){
cin >> s;
for(int i = 0; i <= s.size(); i++){
dp[i][0] = dp[i][1] = LLONG_MAX;
}
if(s[0] == '1'){
dp[0][1] = 0;
dp[0][0] = 1;
}else{
dp[0][0] = 0;
dp[0][1] = 1;
}
for(int i = 1; i < s.size(); i++){
if(s[i] == '1'){
dp[i][0] = dp[i - 1][1] + i + 1;
dp[i][1] = dp[i - 1][0];
}else{
dp[i][1] = dp[i - 1][0] + i + 1;
dp[i][0] = dp[i - 1][1];
}
}
cout << min(dp[s.size() - 1][0], dp[s.size() - 1][1]);
return 0;
}