[ABC267D] Index × A(Not Continuous ver.) 题解

[ABC267D] Index × A(Not Continuous ver.) Solution

更好的阅读体验戳此进入

题面

求序列 $ A_n $ 的长度为 $ m $ 的最大权值子序列 $ B_m $,定义序列 $ B_m $ 的权值为 $ \sum_{i = 1}^m i \times B_i $。输出最大权值。

Solution

提供一种不同的思路

一种显而易见的思路就是考虑 $ i $ 是否选,则 DP 是 $ \texttt{2D0D} $ 的,这里提供一种 $ \texttt{2D1D} \rightarrow \texttt{2D0D} $ 的做法。

我们考虑一个类似 LIS 的做法,考虑令 $ dp(i, j) $ 表示长度为 $ i $ 的以 $ j $ 结尾的子序列的最大权值,转移显然为:

\[dp(i, j) = \max_{k = 1}^{j - 1} dp(i - 1, k) + i \times A_j \]

即考虑从之前的某一个最优子序列拼过来。

这个东西十分显然可以简单写一个前缀和优化,最终复杂度 $ O(n^2) $。

初始值即为 $ dp(0, i) = 0 $,注意初始时需要将除了 $ 0 $ 之外的所有 $ sum $ 都初始化为 $ -\infty $,否则因为负权值可能存在一些不正确的转移。

Code

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;

template < typename T = int >
inline T read(void);

int N, M;
ll A[2100];
ll dp[2100][2100];
ll sum_mx[2100][2100];

int main(){
    memset(sum_mx, 0xc0, sizeof sum_mx);
    N = read(), M = read();
    for(int i = 0; i <= N; ++i)sum_mx[0][i] = 0;
    for(int i = 1; i <= N; ++i)A[i] = read();
    for(int i = 1; i <= M; ++i)
        for(int j = 1; j <= N; ++j)
            dp[i][j] = sum_mx[i - 1][j - 1] + A[j] * i,
            sum_mx[i][j] = max(sum_mx[i][j - 1], dp[i][j]);
    printf("%lld\n", sum_mx[M][N]);
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

UPD

update-2023_01_14 初稿

posted @ 2023-02-15 19:01  Tsawke  阅读(37)  评论(0编辑  收藏  举报