ABC 267 D - Index × A(Not Continuous ver.) ( DP / 01背包 )
https://atcoder.jp/contests/abc267/tasks/abc267_d
题目大意:
给定长度为n的数组a,让我们从中选择m个数字,按顺序
组成B(a1----am)之后,sum=1*a1+……+m*am;
问我们sum最大值是多少?
Sample Input 1
4 2
5 4 -1 8
Sample Output 1
21
Sample Input 2
10 4
-3 1 -4 1 -5 9 -2 6 -5 3
Sample Output 2
54
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL INF=1e9;
const LL N=5000200,M=2002;
LL n,m;
LL a[N],f[M][M];
//f[i][j]表示从前i个数中选j个数字能得到的最大值
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
LL T=1;
//cin>>T;
while(T--)
{
memset(f,-0x3f,sizeof f);
cin>>n>>m;
for(LL i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=0;i<=n;i++)
{
//初始的时候无论有多少个我没有选那就最大值还是0
f[i][0]=0;
}
for(LL i=1;i<=n;i++)//面对第i个数字的时候
{
for(LL j=1;j<=m&&j<=i;j++)//分别假定它作为第几次取值,注意取的次数需要比位置更小
{
//01背包
f[i][j]=max(f[i-1][j-1]+j*a[i],f[i-1][j]);
}
}
/*for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
cout<<f[i][j]<<" ";
}
cout<<endl;
}*/
cout<<f[n][m]<<endl;
}
return 0;
}