Topcoder SRM 654 Div2 1000

Problem

给一个长度为N(N∈[1,2000])的数列An(An∈[?100,100]),设ans=A1?A2?...?An,下面进行M(M∈[1,2000])次操作,每次将A的p[i]的值修改为v[i],即A[p[i]]=v[i],每次只允许加入最多2个括号进入ans等式,问ans的最大值可以是多少?

Solution

dp.. 设dp[i][j]表示从 1 到 i-1 已经有 j 个括弧时候的最大值,j=0时表示没有括弧,j=1时表示(这样子,j=2时表示(( 这个样子,j=3时表示(() 这个样子,j=4时表示(())这个样子。。没了。最后只需要统计 dp[n+1][j] (0<=j<=4)的最大值即可。

My Code

//Hello. I‘m Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
const double pi=acos(-1.0);
//const double eps=1e-9;
#define MOD 1000000007
#define MAXN 3000100
#define M
int dp[2010][10];
class SuccessiveSubtraction2{
public:
    int solve(vector<int>&a){
        for(int i=0;i<=a.size();i++){
            for(int j=0;j<=4;j++){
                dp[i][j]=-(1<<30);
            }
        }
        dp[0][0]=0;
        for(int i=0;i<a.size();i++){
            int x=(i?-a[i]:a[i]);
            dp[i+1][0]=max(dp[i+1][0],dp[i][0]+x);
            if(i>=2){
                dp[i+1][1]=max(dp[i+1][1],dp[i][0]-x);
                dp[i+1][1]=max(dp[i+1][1],dp[i][1]-x);
                dp[i+1][2]=max(dp[i+1][2],dp[i][1]+x);
                dp[i+1][2]=max(dp[i+1][2],dp[i][2]+x);
                dp[i+1][3]=max(dp[i+1][3],dp[i][2]-x);
                dp[i+1][3]=max(dp[i+1][3],dp[i][3]-x);
                dp[i+1][4]=max(dp[i+1][4],dp[i][3]+x);
                dp[i+1][4]=max(dp[i+1][4],dp[i][4]+x);
            }
        }
        int ret=-(1<<30);
        for(int i=0;i<=4;i++){
            ret=max(ret,dp[a.size()][i]);
        }
        return ret;
    }
    vector <int> calc(vector <int> a, vector <int> p, vector <int> v){
        int lenp=gsize(p);
        vector<int>res;
        res.clear();
        rep(i,0,lenp){
            a[p[i]]=v[i];
            int ans=solve(a);
            res.push_back(ans);
        }
        return res;
    }
};
时间: 2024-10-13 01:33:01

Topcoder SRM 654 Div2 1000的相关文章

TOPCODER SRM 686 div2 1000

// TOPCODER SRM 686 div2 1000 Problem Statement 给出一个至多长 100 的字符串,仅包含 ( 和 ),问其中有多少个不重复的,合法的括号子序列. 子序列可以不连续:合法即括号序列的合法:答案模 1,000,000,007. Examples "(())(" Returns: 2 Correct non-empty bracket subsequences are "()" and "(())". &

Topcoder SRM 648 Div2 1000

Problem 给一个长度为N的字符串S,S只含有'A'.'B'.'C'三种元素.给定一个K,要求返回字符串S,使得S中恰好有K对pair(i,j)满足 0=<i<j<N,且 S[i]<S[j].若不存在,则返回空串. Limits Time Limit(ms): 2000 Memory Limit(MB): 256 N: [3, 30] K: [0, N*(N-1)/2 ] Solution 设S中含有n1个'A',n2个'B',n3个'C',设num=n1*n2+n1*n3+n

Topcoder Srm 673 Div2 1000 BearPermutations2

\(>Topcoder \space Srm \space 673 \space Div2 \space 1000 \space BearPermutations2<\) 题目大意 : 对于一个长度为 \(n\) 的排列,定义其的贡献为对其建笛卡尔树,树上有两个儿子的节点其左右儿子在原排列中的距离之和,给出 \(n, Mod\),求所有长度为 \(n\) 的排列的贡献之和对 \(Mod\) 取模的值 \(1 \leq n \leq 100\) 解题思路 : 考虑一个最暴力的 \(dp\) ,设

求拓扑排序的数量,例题 topcoder srm 654 div2 500

周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are numbered from 0 to N-1. Some pairs of rooms are connected by bidirectional passages. The passages have the topology of a tree. That is, there are exactly N-

topcoder SRM 625 DIV2 AddMultiply

由于题目告诉肯定至少存在一种解, 故只需要根据条件遍历一下, vector <int> makeExpression(int y) { vector<int> res; for(int i = -1000; i <=1000; ++ i){ for(int j = -1000; j <= 1000; ++ j){ if(i!=0 && i!=1 && j!=0&& j!=1 ){ int k = y-i*j; if(k&g

topcoder SRM 628 DIV2 BishopMove

题目比较简单. 注意看测试用例2,给的提示 Please note that this is the largest possible return value: whenever there is a solution, there is a solution that uses at most two moves. 最多只有两步 #include <vector> #include <string> #include <list> #include <map&

topcoder SRM 618 DIV2 WritingWords

只需要对word遍历一遍即可 int write(string word) { int cnt = 0; for(int i = 0 ; i < word.length(); ++ i){ cnt+=word[i]-'A'+1; } return cnt; } topcoder SRM 618 DIV2 WritingWords,布布扣,bubuko.com

topcoder SRM 618 DIV2 MovingRooksDiv2

一开始Y1,Y2两个参数看不懂,再看一遍题目后才知道,vector<int>索引代表是行数,值代表的是列 此题数据量不大,直接深度搜索即可 注意这里深度搜索的访问标识不是以前的索引和元素,而是一个交换元素后的整个状态vector<int>,这样可以避免重复元素的搜索 set<vector<int> > visit; bool flag; void dfs(vector<int>& src, vector<int>& d

topcoder SRM 618 DIV2 LongWordsDiv2

此题给出的条件是: (1)word的每个字母都是大写字母(此条件可以忽略,题目给的输入都是大写字母) (2) 相等字符不能连续,即不能出现AABC的连续相同的情况 (3)word中不存在字母组成xyxy的形式,即不存在第一个字符和第3个字符相等同时第2个字符和第4个字符相等的情况 对于第(2)种情况,只需要考虑word[i]!=word[i-1]即可 对于第(3)种情况,用一个4重循环遍历每种可能的情况,然后第一个字符和第3个字符相等同时第2个字符和第4个字符相等,则输出“DisLikes”即可