【题解】AT2273 Addition and Subtraction Hard(DP)

【题解】AT2273 Addition and Subtraction Hard(DP)

一个数对答案最终的贡献是\(+/-1\),决定一个数的在最终答案里的贡献在于它在多少个\(-(\dots)\)之中。

考虑一个\(O(n^3)DP\),设\(dp(i,j)\)表示确定\(i\)个数字前面的左括号,总共有\(j\)个"-("括号需要到时候括回来,根据\(j\)的奇偶性就能够转移。

但是实际上我们不需要记录括号具体的数量,我们只需要知道奇偶性即可。此外,由于一个位置可以括多个括号回来( 像这样\()\big)\Big)\) ),所以\(>1\)的括号既可以看做偶数个,也可以看做奇数个。所以设\(dp(i,0/1/2)\)表示这个位置有\(0/1/>1\)个括号需要括回来,可以选择现在括,也可以留到以后。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;  typedef long long ll;
inline int qr(){
	int ret=0,f=0,c=getchar();
	while(!isdigit(c)) f|=c==45,c=getchar();
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return f?-ret:ret;
}
const int maxn=1e5+5;
int data[maxn],n;
ll dp[maxn][3];

int main(){
	memset(dp,0xcc,sizeof dp);
	n=qr();
	for(int t=1;t<=n;++t) data[t]=qr();
	dp[0][0]=0;
	for(int t=1;t<=n;++t)
		if(data[t]>0){
			dp[t][0]=max({dp[t][0],dp[t-1][0]+data[t],dp[t-1][1]+data[t],dp[t-1][2]+data[t]});
			dp[t][1]=max({dp[t][1],dp[t-1][1]-data[t],dp[t-1][2]-data[t]});
			dp[t][2]=max({dp[t][2],dp[t-1][2]+data[t]});
		}else{
			data[t]=-data[t];
			dp[t][0]=max({dp[t][0],dp[t-1][0]-data[t],dp[t-1][1]-data[t],dp[t-1][2]-data[t]});
			dp[t][1]=max({dp[t][1],dp[t-1][0]-data[t],dp[t-1][1]+data[t],dp[t-1][2]+data[t]});
			dp[t][2]=max({dp[t][2],dp[t-1][1]+data[t],dp[t-1][2]+data[t]});
		}
	cout<<max({dp[n][0],dp[n][1],dp[n][2]})<<endl;
	return 0;	
}


posted @ 2020-04-29 19:23  谁是鸽王  阅读(224)  评论(0编辑  收藏  举报