算法题:codeforces 1550B. Maximum Cost Deletion(题目+思路+代码+注释)

在这里插入图片描述

题目

1550B. Maximum Cost Deletion
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a string s of length n consisting only of the characters 0 and 1.

You perform the following operation until the string becomes empty: choose some consecutive substring of equal characters, erase it from the string and glue the remaining two parts together (any of them can be empty) in the same order. For example, if you erase the substring 111 from the string 111110, you will get the string 110. When you delete a substring of length l, you get a⋅l+b points.

Your task is to calculate the maximum number of points that you can score in total, if you have to make the given string empty.

Input
The first line contains a single integer t (1≤t≤2000) — the number of testcases.

The first line of each testcase contains three integers n, a and b (1≤n≤100;−100≤a,b≤100) — the length of the string s and the parameters a and b.

The second line contains the string s. The string s consists only of the characters 0 and 1.

Output
For each testcase, print a single integer — the maximum number of points that you can score.

Example
input
3
3 2 0
000
5 -2 5
11001
6 1 -4
100111

output
6
15
-2
Note
In the first example, it is enough to delete the entire string, then we will get 2⋅3+0=6 points.

In the second example, if we delete characters one by one, then for each deleted character we will get (−2)⋅1+5=3 points, i. e. 15 points in total.

In the third example, we can delete the substring 00 from the string 100111, we get 1⋅2+(−4)=−2 points, and the string will be equal to 1111, removing it entirely we get 1⋅4+(−4)=0 points. In total, we got −2 points for 2 operations.
题目来自:https://codeforces.com/contest/1550/problem/B

思路

  • 题目中需要我们求删除的最大得分数(每删除一段,按照公式al+b增加得分),a和b是给定的,l是我们自己决定,我们可以知道,假设长度为n的字符串一次性删除,得分是an+b,假设分n次删除得分是n*(a+b)=a*n+b+(n-1)*b,由此我们可以知道,要想分数越多,
  • 那么当b大于0的时候,删除次数越多得分越高,那么最多必定是an+nb。
  • 当b小于0的时候,删除次数越少得分越高,删除次数最少怎么算呢?
  • 而且当多次删除的时候我们的得分公式为 al+b,我们拆开来看,既然前面说到了不管你多少次删除,a都是n个,只有b的个数受删除次数 t 影响,那我们最后得分的公式就等于 an + t * b
  • 100011001
  • 1001000
  • 既然是由0和1组成的,每次删连续相同的,那么,0的段数和1的段数要么是相等的(第一个字符和最后一个字符不相同),要么是一个比另一个多一段(第一个字符和最后一个字符相同),那么其实最少的删除次数就是
  • 首尾字符相同时,先删和首字符不同的,再最后删除首字符的长串,删除次数是 非首字符的段数+1=首字符的段数
  • 首尾字符不相同时,两个字符的段数都是一样的,先删除首字符的所有段,再删除非首字符的长串,删除次数是 首字符的段数+1
  • 那么最后将删除次数t代入即可, a * n + t * b

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //创建Scanner用于读取
        Scanner scanner = new Scanner(System.in);
        //测试样例个数读取
        int testCases,n,a,b;
        String s;
        testCases = Integer.parseInt(scanner.nextLine());
        //读取数据
        for (int i = 0 ;i< testCases;i++){
            String firstLine = scanner.nextLine();
            String[] paras = firstLine.split(" ");
            n = Integer.parseInt(paras[0]);
            a = Integer.parseInt(paras[1]);
            b = Integer.parseInt(paras[2]);
            s = scanner.nextLine();
            System.out.println(calculateMaxScore(n,a,b,s));
        }

    }
    /**
     * 计算一个测试样例的最大分数
     * @param n
     * @param a
     * @param b
     * @param s
     * @return
     */
    public static int calculateMaxScore(int n,int a,int b,String s){
        //假设有 11,分两次是2(a*1+b),一次是a*2+b,其实无论怎么,a的个数是一定等于n的,只有b因为擦除次数不同相加个数不同
        if (b >= 0){
            //次数越多越好
            return n*(a+b);
        }else {
            //找第一个字符有多少段连续的子串
            char c = s.charAt(0),now = c;
            int block = 1;
            for (int i = 1,len = s.length();i < len;i++){
                if (now != s.charAt(i)){
                    if (s.charAt(i) == c){
                        block++;
                    }
                    now = s.charAt(i);
                }
            }
            //如果最后一个字符和第一个字符不一样则还需要加1
            if (s.charAt(s.length()-1) != c){
                block++;
            }
            return n*a + block*b;
        }
    }

}
posted @ 2021-07-29 14:26  HumorChen99  阅读(2)  评论(0编辑  收藏  举报  来源