dd爱科学1.0

题目描述

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

输入描述:

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

输入

5
ACEBF

输出

1

解析

这题的本质就是求最长的非递减子序列,其余的字符需要进行修改。因此有两种方法

dp

对于字符 s [ i ] s[i] s[i],他只能接在一个字典序小于等于 s [ i ] s[i] s[i]的后面,因此我们很容易得到转移方程
我们设 c h a r I n d e x [ j ] charIndex[j] charIndex[j]为上一个字符 j j j的下标
d p [ i ] dp[i] dp[i]考虑 i i i个字符并且以第 i i i个字符结尾的的最长子序列长度
d p [ i ] = m a x ( d p [ i ] , d p [ c h a r I n d e x [ j ] ] ) ( j < s [ i ] ) dp[i]=max(dp[i],dp[ charIndex[j]])(j<s[i]) dp[i]=max(dp[i],dp[charIndex[j]])(j<s[i])

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000005;
char s[N];
int charIndex[26];//存储上一个字符的下标
int dp[N];//dp[i] 表示[1,i]最小代价
int main() {
    int n ;
    scanf("%d%s",&n,s+1);
    int res=0,mx=0;
    for(int i=1;i<=n;i++){
        int a=s[i]-'A';
        for(int j=0;j<=a;j++){
            dp[i]=max(dp[i],dp[charIndex[j]]+1);
        }
        mx=max(dp[i],mx);
        charIndex[a]=i;
    }
    cout<<n-mx;
}


二分+贪心

同样也是找最长非递减子序列,我们可以用一个简单的贪心思维去考虑,最长的非递减子序列应该是越紧凑越好,

以输入序列 [0, 8, 4, 12, 2] 为例:

第一步插入 0,d = [0]d=[0];

第二步插入 8,d = [0, 8]d=[0,8];

第三步插入 4,d = [0, 4]d=[0,4];

第四步插入 12,d = [0, 4, 12]d=[0,4,12];

第五步插入 2,d = [0, 2, 12]d=[0,2,12]。

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
int r[1000010];
int len = 1;
int main(){
    cin>>n;
    cin>>s;
    r[1] = s[0] - 'A';
    for(int i = 1; i < n ;i++){
        int pos = upper_bound(r + 1, r + len + 1, s[i] - 'A') - r;//大于s[i]的下标
        r[pos] = s[i] - 'A';//
        len = max(len, pos);
    }
    cout<<n - len<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值