一道贪心:加括号使算式的值最大

问题描述

给定一个算术表达式形如1+3-5-4+6,表达式中的运算数全部都是正数,运算符全部是加号或者减号。
现在可以给算术表达式加任意多的括号,使得表达式的值最大。
如对于1+3-6-9+4-5-7+8,可以1+3-(6-9)+4-(5-7)+8,最优的方案是1+3-(6-9+4-5-7)+8

数据格式

T 例子个数
n1 第一个例子的运算数个数
1+3-6-9+4-5-7+8 算数表达式
n2
......

输出一个数字,表示表达式的最大值。
数据范围:运算数个数为1e5。

解析

  • 最优答案中,括号只加在减号前面
  • 最优答案中,若干个加号之间不加括号,例如3-4+5+6+7-8,其中5,6,7之间肯定没有括号
  • 最优答案中,括号肯定不会嵌套
  • 最优答案中,形如-a+b-c,如果c<b,那么-(a)+b-(c 比-(a+b-c 结果要好。

贪心的原则就是,既然无论如何都要给右面留下左括号,那么左括号的位置必然是最优的。

代码

#include<iostream>
using namespace std;
const int maxn = 1e5 + 7;
typedef  long long ll;
int a[maxn];
char op[maxn];
int m;
int find(int ind) {
    for (int i = ind; i < m; i++) {
        if ( op[i] == '+' &&(i >= m - 1 || a[i + 1] < a[i])) {
            return i-1;
        }
    }
    return m - 1;
}
ll sum_range(int f, int t) {
    ll s = 0;
    for (int i = f; i <= t; i++) {
        int value = (op[i] == '+' ? 1 : -1)*a[i];
        s -= value;
    }
    return s;
}
ll solve() {
    //压缩正号
    int i = 0;
    for (int j = 1; j < m; j++) {
        if (op[j] == '+') {
            if (op[i] == '+')
                a[i] += a[j];
            else {
                i++;
                op[i] = '+';
                a[i] = a[j];
            }
        }
        else {
            i++;
            op[i] = '-';
            a[i] = a[j];
        }
    }
    m = i + 1;
    ll s = 0;
    //如果我后面的负数比我大,我就要牺牲
    for (int i = 0; i < m; i++) {
        if (op[i] == '-') {
            int j = find(i);
            s += -a[i]+sum_range(i+1, j);
            i = j;
        }
        else {
            s += a[i];
        }
    }
    return s;
}
int main() {
    freopen("in.txt", "r", stdin);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> m;
        op[0] = '+';
        for (int j = 0; j < m; j++) {
            if (j > 0) {
                cin >> op[j];
            }
            cin >> a[j];
        }
        cout << solve() << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/weiyinfu/p/9818616.html

时间: 2024-11-25 09:24:50

一道贪心:加括号使算式的值最大的相关文章

c语言:宏里面参数不加括号容易出错,在使用时尽量加括号及举例

宏里面参数不加括号容易出错,在使用时尽量加括号 程序1: #include<stdio.h> #define SQARE(X) X*X int main() { int  n = 10; int m=SQARE(n); printf("m=%d\n",m); return 0; } 结果: m=100 请按任意键继续. . . 分析:貌似没有出问题,请看下面两个例子 程序2: #include<stdio.h> #define SQARE(X) X*X int 

函数基础重点掌握内容:创建函数、return返回单个值、return返回多个值、函数名加括号与不加括号的区别

##比较两个数大小 #有参函数!!! def compare(s,t): if s > t: print(s) else: print(t) f=compare compare(1000,30) f(1800,30) """有几个参数传几个参数,形参对应实参,一个也不能少""" ''' 2.函数名加括号与不加括号的区别: 函数名加括号与不加括号的区别: --在这个函数中,return返回的是inner, 内部其实是返回inner函数的运行结

没有括号的算式 面试算法(四)

import java.util.Scanner; public class Test { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String next = scanner.next(); System.out.println(test(next)); } /** * 有一个写在黑板上的加减法算式,运算符只包含加号.减号和括号,但其中的括号被清洁工擦去了.现在需要你写一

”高精度整数删去若干位以使剩下的值最小“问题

问题描述: 键盘输入一个高精度的正整数N(不超过240位) ,去掉其中任意M个数字后剩下的数字按原左右次序将组成一个新的正整数. 编程对给定的N和M,寻找一种方案使得剩下的数字组成的新数最小.输出组成的新的正整数. 输入数据均不需判错. 如果去掉了某几个位后得到的新整数开头为0,保留0. 输入: 本题有多组测试数据,每组测试数据占一行. 一个高精度正整数N(N不超过240位)一个正整数M.(M为不大于N的长度的正整数) N,M由一个空格分开. 456547 1 456547 2 456547 3

关于JS中的方法是否加括号的问题

js中的方法什么时候加括号什么时候不加括号呢,我们有时候经常就搞不清楚,记住下面这几点就好理解了. 1.函数做参数时都不要加括号. function fun(a){ alert(a); } function getE(fun,e){ fun(e); } getE(fun,3);//弹出3,这里把函数fun当成实参传入,所以就不用加括号了. 2.函数调用的时候是要加括号的,上面这个例子中getE这个函数调用的时候,不管有没有参数,都是要加括号的. 3.函数作为赋值符号右边的时候,无括号表示的是传递

关于vue ,v-on 绑定事件时,函数名加括号和不加括号的区别

作者:DDFE链接:https://www.zhihu.com/question/55753541/answer/146504270来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 从官方的文档 事件处理器 - Vue.js 中可以看出通过 `v-on` 中既可以执行一段代码.一个方法.内联 JavaScript 语句,根据不同的情况 Vue 会做不同的处理,具体可以从源码中可以看出(2.1.10版本),在编译阶段,会根据抽象HTML语法树生成代码,从 https:

模拟计算器:一个带加减乘除和括号的表达式 求值

//整数,加,减,乘,除,多重小括号表达式的求值,例如 -1+(2-(3+4)/7)*5,(不带输入检查): #include <sstream> #include <iostream> #include <string> using namespace std; int sToI(string s); string iToS(int myInt); string sCalculate(string s1, string s2, char opr); string no

调用类时,加括号和不加括号的区别

class ListNode: def __init__(self, x): self.val = x self.next = None a = ListNodea.val = 1print(ListNode.val) # 返回 1 class ListNode2: val = 1 def __init__(self, x): self.val = x self.next = None print(ListNode2.val) # 返回 1 b = ListNode(3) # 这是在实例化对象,

闭包函数之函数加括号和不加括号的意义

import time # 闭包函数 def outer(): x = 100 def inner(): print(x) return inner fun = outer() print(fun) #函数不加括号,调用的是函数本身[function] # <function outer.<locals>.inner at 0x0000000001F151E0> time.sleep(5) fun() #函数加括号,调用的是函数的return结果. time.sleep(5) pr