dd 爱科学

24 阅读2分钟

题目描述

大科学家dddddd最近在研究转基因白菜,白菜的基因序列由一串大写英文字母构成,dddddd经过严谨的推理证明发现,只有当白菜的基因序列呈按位非递减形式时,这株白菜的高附加值将达到最高,于是优秀的dddddd开始着手修改白菜的基因序列,dddddd每次修改基因序列的任意位需要的代价是111,dddddd想知道,修改白菜的基因序列使其高附加值达到最高,所需要的最小代价的是多少。

输入描述:

第一行一个正整数n(1≤n≤1000000)
第二行一个长度为n的字符串,表示所给白菜的基因序列
保证给出字符串中有且仅有大写英文字母

输出描述:

输出一行,表示最小代价

示例1

输入

5 ACEBF

5
ACEBF

输出

1

1

说明

改成ACEEF或者ACEFF,都只用改动一个字符,所需代价最小为1

解题思路

转化成找最长递增序列(非严格),由于有时间限制,所有采用二分查找,而不是动态规划进行优化

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    // Write your code here
    let params = [];
    while ((line = await readline())) {
        let tokens = line.split(" ");
        // let a = parseInt(tokens[0]);
        // let b = parseInt(tokens[1]);
        // console.log(a + b);
        params.push(tokens);
    }
    // console.log(params)
    let n = parseInt(params[0][0]);
    let str = params[1][0];
    // console.log(n,str)
    // console.log('A'.charCodeAt(0)-'B'.charCodeAt(0))
    // console.log("A"+1)
    let arr = str.split("");
    // console.log(arr)
    let dp = []; // 使用二分法 维持一个最大非递减数组
    let len = 0;
    for (let i = 0; i < arr.length; i++) {
        // 判断当前元素是否不小于dp的最大元素
        if (i == 0 || arr[i].charCodeAt(0) >= dp[len - 1].charCodeAt(0)) {
            dp[len] = arr[i];
            len++;
        } else {
            // 找到dp中比它小的元素,然后更新它,原先长度保持不变,只是为未来可以在后面添加元素腾出了新的空间
            let left = 0;
            let right = len - 1;
            let pos = -1;
            while (left <= right) {
                let mid = Math.floor((right + left) / 2);
                if (dp[mid].charCodeAt(0) > arr[i].charCodeAt(0)) {
                    pos = mid;
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            if (pos != -1) {
                // 替换掉原有的元素
                dp[pos] = arr[i];
            }
        }
    }
    // console.log(dp)
    console.log(arr.length - dp.length);
})();