写点什么

2022-11-30:小红拿到了一个仅由 r、e、d 组成的字符串 她定义一个字符 e 为“好 e“ : 当且仅当这个 e 字符和 r、d 相邻 例如“reeder“只有一个“好 e“,前两个 e 都不是“好 e“,只有第三个

  • 2022-11-30
    北京
  • 本文字数:1980 字

    阅读完需:约 6 分钟

2022-11-30:小红拿到了一个仅由r、e、d组成的字符串 她定义一个字符e为“好e“ : 当且仅当这个e字符和r、d相邻 例如“reeder“只有一个“好e“,前两个e都不是“好e“,只有第三个

2022-11-30:小红拿到了一个仅由 r、e、d 组成的字符串她定义一个字符 e 为"好 e" : 当且仅当这个 e 字符和 r、d 相邻例如"reeder"只有一个"好 e",前两个 e 都不是"好 e",只有第三个 e 是"好 e"小红每次可以将任意字符修改为任意字符,即三种字符可以相互修改她希望"好 e"的数量尽可能多小红想知道,自己最少要修改多少次输入一个只有 r、e、d 三种字符的字符串长度 <= 2 * 10^5。输出最小修改次数。来自网易。


答案 2022-11-30:


动态规划。奇数,1,3,5,7 一定是 e。


代码用 rust 编写。代码如下:


use std::iter::repeat;
fn main() { let str = "rrredrr"; let ans = min_cost(str); //dereder println!("ans = {}", ans);}
fn min_cost(str: &str) -> i32 { let n = str.len() as i32; if n < 3 { return -1; } let mut arr: Vec<i32> = repeat(0).take(n as usize).collect(); // d认为是0,e认为是1,r认为是2 let strc: Vec<char> = str.chars().collect(); for i in 0..n { let cur = strc[i as usize]; if cur == 'd' { arr[i as usize] = 0; } else if cur == 'e' { arr[i as usize] = 1; } else { arr[i as usize] = 2; } } // 通过上面的转化,问题变成了: // 1的左右,一定要被0和2包围,这个1才是"好1" // 请让"好1"的尽量多,返回最少的修改代价 let mut max_good = 0; let mut min_cost = i32::MAX; for prepre in 0..3 { for pre in 0..3 { let mut cost = if arr[0] == prepre { 0 } else { 1 }; cost += if arr[1] == pre { 0 } else { 1 }; let cur = process(&mut arr, 2, prepre, pre); if cur.max_good > max_good { max_good = cur.max_good; min_cost = cur.min_cost + cost; } else if cur.max_good == max_good { min_cost = get_min(min_cost, cur.min_cost + cost); } } } return min_cost;}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T { if a < b { a } else { b }}struct Info { max_good: i32, min_cost: i32,}
impl Info { fn new(a: i32, b: i32) -> Self { Self { max_good: a, min_cost: b, } }}// 暴力递归// 可以自己改成动态规划// arr[index-2]位置的数值是prepre// arr[index-1]位置的数值是pre// 在这种情况下,请让arr[index...]上的好1尽量多// 返回:// 尽量多的"好1",是多少?// 得到尽量多的"好1",最小代价是多少?fn process(arr: &mut Vec<i32>, index: i32, prepre: i32, pre: i32) -> Info { if index == arr.len() as i32 { return Info::new(0, 0); } // 可能性1,arr[index],变成0 let mut p1_value = if prepre == 2 && pre == 1 { 1 } else { 0 }; let mut p1_cost = if arr[index as usize] == 0 { 0 } else { 1 }; let mut info = process(arr, index + 1, pre, 0); p1_value += info.max_good; p1_cost += info.min_cost; // 可能性2,arr[index],变成1 let mut p2_value = 0; let mut p2_cost = if arr[index as usize] == 1 { 0 } else { 1 }; info = process(arr, index + 1, pre, 1); p2_value += info.max_good; p2_cost += info.min_cost; // 可能性3,arr[index],变成2 let mut p3_value = if prepre == 0 && pre == 1 { 1 } else { 0 }; let mut p3_cost = if arr[index as usize] == 2 { 0 } else { 1 }; info = process(arr, index + 1, pre, 2); p3_value += info.max_good; p3_cost += info.min_cost; // 开始决策,选出三种可能性中的最优解 let mut max_good = 0; let mut min_cost = i32::MAX; if p1_value > max_good { max_good = p1_value; min_cost = p1_cost; } else if p1_value == max_good { min_cost = get_min(min_cost, p1_cost); } if p2_value > max_good { max_good = p2_value; min_cost = p2_cost; } else if p2_value == max_good { min_cost = get_min(min_cost, p2_cost); } if p3_value > max_good { max_good = p3_value; min_cost = p3_cost; } else if p3_value == max_good { min_cost = get_min(min_cost, p3_cost); } return Info::new(max_good, min_cost);}
复制代码


执行结果如下:





左神java代码

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2021-02-15 加入

还未添加个人简介

评论

发布
暂无评论
2022-11-30:小红拿到了一个仅由r、e、d组成的字符串 她定义一个字符e为“好e“ : 当且仅当这个e字符和r、d相邻 例如“reeder“只有一个“好e“,前两个e都不是“好e“,只有第三个_算法_福大大架构师每日一题_InfoQ写作社区