ABC219H
做起来真的没有想象中的那么难(?)感谢 @zltqwq 讲的好题/bx
首先考虑蜡烛可以烧到负数长度怎么做。发现这题等同于关路灯。设个状态:
然后加入只能烧到
此时就可以将这个问题转化一下:你可以在这些蜡烛中选任意多个删去,并根据上面的方式计算,并将所有结果取
现在是不是就变得明朗了呢?
所以可以直接把选了多少个塞进状态。设
code:
点击查看代码
int n,m;
ll dp[N][N][N][2];
struct node{
ll c,p;
}e[N];
inline ll cost(int l,int r,int p,int k,int op){
return max(dp[l][r][k][op]-(op?abs(e[r].p-e[p].p):abs(e[l].p-e[p].p))*k,dp[l][r][k+1][op]-(op?abs(e[r].p-e[p].p):abs(e[l].p-e[p].p))*(k+1)+e[p].c);
}
inline bool cmp(node x,node y){
return x.p!=y.p?x.p<y.p:x.c>y.c;
}
void Yorushika(){
scanf("%d",&n);
rep(i,1,n){
scanf("%lld%lld",&e[i].p,&e[i].c);
}
e[++n]={-inf,0};
sort(e+1,e+n+1,cmp);
int s=0;
rep(i,1,n){
if(!e[i].p)
s=i;
}
mems(dp,-0x3f);
rep(i,0,n){
dp[s][s][i][0]=dp[s][s][i][1]=0;
}
ll ans=0;
drep(i,s,1){
rep(j,s,n){
if(i==j)
continue;
rep(k,0,n){
dp[i][j][k][0]=max(cost(i+1,j,i,k,0),cost(i+1,j,i,k,1));
dp[i][j][k][1]=max(cost(i,j-1,j,k,0),cost(i,j-1,j,k,1));
ans=max(ans,max(dp[i][j][k][0],dp[i][j][k][1]));
}
}
}
printf("%lld\n",ans);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}