[ABC163E] Active Infants

思路

我们可能会第一时间觉得这时一个贪心但是我们发现这是错的,因为我们的 \(a_i\) 后还跟了一个系数而有可能系数会决定所有而不一定是 \(a_i\)。然后我们来想 dp,我们定义 \(f_{i,l}\) 为将前 \(i\) 个数填到 \(l\sim l+i-1\) 的最大值,但是我们可以发现这样的话我们需要枚举第 \(i\) 个数填在哪里,那么这样无法通过此题,所以我们用一个贪心,先将 \(a_i\) 排序,那么我们因为 \(a_i\) 越大所以我们就只能将 \(a_i\)\(l\)\(l+i-1\) 上方才会最大。

所以我们便可以得到一个状态转移方程为 \(f_{i,l}=\max(f_{i-1,l}+a_{i}\times |i-wei_i|,f_{i-1,l+1}+a_{i}\times|(i+l-1)-wei_i|)\) 这里的 \(wei_i\) 存的是在原数组中 \(a_i\) 的位置。

最后的答案就是 \(f_{n,1}\)

代码

#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define rep1(i,x,y) for(int i=x;i>=y;i--)
#define fire signed
#define kong putchar(' ')
#define end putchar('\n')
#define in(x) scanf("%lld",&x)
#define lcm(x,y) x*y/__gcd(x,y)
#define w(x)  while(x--)
#define il inline
il void print(int x) {
	if(x>=10) print(x/10);
	putchar(x%10+'0');
}
struct node{
	int x,id;
}s[1010100];
int n;
bool cmp(node a,node b) {
	return a.x<b.x;
} 
int f[2100][2100];
fire main() {
	in(n);
	rep(i,1,n) in(s[i].x),s[i].id=i;
	sort(s+1,s+1+n,cmp);
	f[0][0]=1;
	rep(l,1,n) {
		for(int i=1;i+l-1<=n;i++) {
			f[l][i]=max(f[l-1][i]+s[l].x*abs(s[l].id-(l+i-1)),f[l-1][i+1]+s[l].x*abs(s[l].id-i)); 
		}
	}
	cout<<f[n][1];
	return false;
}

posted @ 2024-01-31 11:44  highkj  阅读(22)  评论(0)    收藏  举报