传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3675

http://uoj.ac/problem/104

【题解】

当时想的时候猜了下从前往后分比较优。

后来证明了一下怎么分都一样。。可以把贡献式子拆开来分析。

这样分析完就可以得到贡献=Σ每两个块的和的积

那么我们整理可以得到贡献=Σ第i个块的和*(前面所有块的和)

那么有dp: f[i,j]表示到第i块,选择的数是a[1]...a[j]的贡献max。

那么直接dp有50分。

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1e5 + 10, N = 210;
const int mod = 1e9+7;

# define RG register
# define ST static

int n, K, a[M];
ll s[M], f[N][M];
int pre[N][M];

inline void prt(int i, int j) {
    if(i == 1) return;
    prt(i-1, pre[i][j]);
    printf("%d ", pre[i][j]);
}

int main() {
    scanf("%d%d", &n, &K);
    for (int i=1; i<=n; ++i) scanf("%d", &a[i]), s[i] = s[i-1] + a[i];
    for (int i=2; i<=K+1; ++i) 
        for (int j=1; j<=n; ++j) {
            f[i][j] = -1e18;
            for (int k=1; k<j; ++k) {
                if(f[i][j] < f[i-1][k] + (s[j]-s[k])*s[k]) {
                    f[i][j] = f[i-1][k] + (s[j]-s[k])*s[k];
                    pre[i][j] = k;
                }
            }
        }
    printf("%lld\n", f[K+1][n]);
    prt(K+1, n);
    return 0;
}
View Code

相关文章:

  • 2021-09-18
  • 2021-12-24
  • 2022-02-03
  • 2022-12-23
  • 2022-02-16
  • 2021-08-21
  • 2021-07-18
猜你喜欢
  • 2021-10-31
  • 2021-06-15
  • 2021-12-10
  • 2022-02-14
相关资源
相似解决方案