ABC E - Active Infants 贪心 dp
LINK:Active Infants
一个快省选的人 还在写ABC(莫名觉得丢人
不过也无所谓了.
首先考虑 随便一个排列 我们考虑一下其是不是最优的 容易发现如果最大值没有在边界上的话我们直接把它放到边界上 显然会更优。
接下来考虑次大值等等。可以发现从大到小排序后 前面的值都是紧贴着边界放的。
如果直接贪心的放的 对于值相同的 我们或许还是可以解决的。
不过考虑一个问题 一个值当前两边都是可以放的 那么放左和放右就会对下一个数字有后效性的影响。
考虑dp 容易发现我们每次放数字都是紧贴着边界放的 所以我们可以用dp来描述这个过程。
f[i][j]表示前i个数放j个数在前面的最大值。
容易发现dp一下刚才的问题就得到解决了。把一些最优的状态集合描述出来了。
对于最优方案来说 我们的dp状态是吻合的。
const ll MAXN=2010;
ll n,ans;
ll f[MAXN][MAXN];
struct wy{ll x,id;}t[MAXN];
inline ll cmp(wy a,wy b){return a.x>b.x;}
signed main()
{
//freopen("1.in","r",stdin);
get(n);
rep(1,n,i)t[i]=(wy){read(),i};
sort(t+1,t+1+n,cmp);
rep(1,n,i)
{
rep(0,i,j)
{
if(j<=i-1)f[i][j]=max(f[i][j],f[i-1][j]+abs(t[i].id-(n-(i-1-j)))*t[i].x);
if(j>=1)f[i][j]=max(f[i][j],f[i-1][j-1]+abs(t[i].id-j)*t[i].x);
}
}
rep(0,n,i)ans=max(ans,f[n][i]);
putl(ans);
return 0;
}