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;
}
posted @ 2020-04-23 21:13  chdy  阅读(160)  评论(0编辑  收藏  举报