[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;
}

浙公网安备 33010602011771号