题目链接:洛谷P4870 [BalticOI 2009 甲虫]
题意:数轴上有 n n n 滴露水,每滴露水 m m m 个单位水分,每过一个单位时间每滴露水流失一单位水分,请根据露水的坐标,计算甲虫最多能喝到的水
首先对露水按坐标排序,考虑区间DP,不难想到用 d p [ l ] [ r ] [ 0 / 1 ] dp[l][r][0/1] dp[l][r][0/1] 表示吃完区间 l l l 到 r r r 的露水,最后停留在左端 / 右端 的最大收益。由于每个单位时间露水的水分有变化,但在这个 dp 中无法表示时间,怎么处理呢?
——费用提前计算
在移动过程中减去丢失的水量,可以直接假设现在的露水水分为 m m m ,因为时间对当前露水的减少量已经在转移过程中提前减去了
类似题目推荐:P1220关路灯、 P2466 [SDOI2008] Sue的小球
#include <bits/stdc++.h>
using namespace std;
int N,m,a[305],ans,dp[305][305][2];
int main(){
scanf("%d%d",&N,&m);
for(int i=1;i<=N;i++)scanf("%d",&a[i]);
sort(a+1,a+1+N);
for(int n=1;n<=N;n++){
memset(dp,0,sizeof(dp));
for(int i=1;i<=N;i++)dp[i][i][0]=dp[i][i][1]=m-abs(a[i])*n,ans=max(ans,dp[i][i][0]);
for(int d=2;d<=n;d++){
for(int l=1,r=d;r<=N;l++,r++){
dp[l][r][0]=max(dp[l+1][r][0]+m-abs(a[l+1]-a[l])*(n-d+1),dp[l+1][r][1]+m-abs(a[r]-a[l])*(n-d+1));
dp[l][r][1]=max(dp[l][r-1][1]+m-abs(a[r]-a[r-1])*(n-d+1),dp[l][r-1][0]+m-abs(a[r]-a[l])*(n-d+1));
ans=max(ans,max(dp[l][r][1],dp[l][r][0]));
}
}
}
printf("%d\n",ans);
return 0;
}