【题解】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;
}
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!