31. 字符串的最大价值(卡码网第二期模拟笔试)

31. 字符串的最大价值(第二期模拟笔试)

题目描述

给定一个字符串 S(S.length < 10000),只包含 0 和 1 两个数字,下标从 1 开始,设第 i 位的价值为 vali,则vali的定义如下:
当 i = 1 时:val1 = 1;
当 i > 1 时:
若Si != S(i - 1):vali = 1,
若Si == S(i - 1):vali = val(i - 1) + 1;
字符串 S 的总价值等于 val1 + val2 + … + valn(n为字符串 S 的长度)。
你可以任意删除字符串 S 中的任意字符,使得字符串 S 的总价值能够达到最大。

输入

输入只有一行,为字符串 S

输出

输出一个整数代表答案

样例输入

010101

样例输出

7

提示

提示
删除一些字符后,S变为 0001 或 0111 时能够达到最大价值。

题解1(C++版本)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e4 + 3; //测试数据的范围超过5000了

int n, cnt0, cnt1;
int start0, end0; //start0,end0分别表示字符'0'在字符串s中第一个,最后一个出现的位置
int start1, end1; //start1,end1分别表示字符'0'在字符串s中第一个,最后一个出现的位置
char s[N];

LL Max(LL a, LL b){
    return a > b ? a : b;
}
int main(){
    scanf("%s", s + 1);
    n = strlen(s + 1);
    //printf("%d\n", n);
    for(int i = 1;i <= n; i++){
        if(s[i] == '0') {
            cnt0 = cnt0 + 1;
            if(!start0){
                start0 = i;
            }
            end0 = i;
        }
        else {
            cnt1 = cnt1 + 1;
            if(!start1){
                start1 = i;
            }
            end1 = i;
        }
    }
    LL sum0 = 0; //统计最长长度的连续0的个数的价值
    //首项为1,尾项为(start0 - 1),项数为(start0 - 1)的等差数列求和
    sum0 += (1LL + start0 - 1LL)*(start0 - 1LL)/2;
    //首项为1,尾项为cnt0,项数为cnt0的等差数列求和
    sum0 += (1LL + cnt0) * cnt0/2; 
    //首项为1,尾项为(n - end0),项数为(n - end0)的等差数列求和
    sum0 += (1LL + (n - end0))*(n - end0)/2;
    
    LL sum1 = 0; //统计最长长度的连续1的个数的价值
    //首项为1,尾项为(start1 - 1),项数为(start1 - 1)的等差数列求和
    sum1 += (1LL + start1 - 1LL)*(start1 - 1LL)/2;
    //首项为1,尾项为cnt1,项数为cnt1的等差数列求和
    sum1 += (1LL + cnt1) * cnt1/2; 
    //首项为1,尾项为(n - end1),项数为(n - end1)的等差数列求和
    sum1 += (1LL + (n - end1))*(n - end1)/2;
    printf("%lld\n", Max(sum0, sum1));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值