求序列
提供一种不同的思路。
一种显而易见的思路就是考虑
我们考虑一个类似 LIS 的做法,考虑令
即考虑从之前的某一个最优子序列拼过来。
这个东西十分显然可以简单写一个前缀和优化,最终复杂度
初始值即为
xxxxxxxxxx
581
2
3
4
5
6
7
8
9
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int x){return rndd(1, 100) <= x;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20typedef long double ld;
21
22template < typename T = int >
23inline T read(void);
24
25int N, M;
26ll A[2100];
27ll dp[2100][2100];
28ll sum_mx[2100][2100];
29
30int main(){
31 memset(sum_mx, 0xc0, sizeof sum_mx);
32 N = read(), M = read();
33 for(int i = 0; i <= N; ++i)sum_mx[0][i] = 0;
34 for(int i = 1; i <= N; ++i)A[i] = read();
35 for(int i = 1; i <= M; ++i)
36 for(int j = 1; j <= N; ++j)
37 dp[i][j] = sum_mx[i - 1][j - 1] + A[j] * i,
38 sum_mx[i][j] = max(sum_mx[i][j - 1], dp[i][j]);
39 printf("%lld\n", sum_mx[M][N]);
40 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
41 return 0;
42}
43
44template < typename T >
45inline T read(void){
46 T ret(0);
47 int flag(1);
48 char c = getchar();
49 while(c != '-' && !isdigit(c))c = getchar();
50 if(c == '-')flag = -1, c = getchar();
51 while(isdigit(c)){
52 ret *= 10;
53 ret += int(c - '0');
54 c = getchar();
55 }
56 ret *= flag;
57 return ret;
58}
update-2023_01_14 初稿