羅区P2672貪欲なセールスマンの問題解決

トピックリンク:https://www.luogu.org/problem/P2672
この質問は貪欲、貪欲考えがあるさ:
選択し\(m個\)最大疲労値ファミリは、以下の2つのシナリオの大きくなければなりません:

  • プログラム:選択し\([I] \)の最大の\(M \)家族。
  • スキーム2:選択\([I] \)最大\(M-1 \)ファミリー、及び残り\(N-(M-1) \) で家族\(2 \回S [I ] + [I] \)家族の中で最大

したがって、私たちは与えることができます\(\ N-を)によると、家族([I] \)\ソート金星を降順。
[開く3つの配列(配列DPを解決する3つ使用します)。

  • suma[i]:示し\(\ sum_ ^ {J} = {I} 1 A [J] + 2 \時間\ MAX_ 1} = {J ^ {I}(S [J])\。)、誘導された式:suma[i] = suma[i-1] + a[i]
  • maxs[i]:示し\(。\ MAX_ J = {I} 1} ^ {S [J] \) 誘導された式:maxs[i] = maxs[i-1] + s[i]
  • maxsa[i]:示し\(\ MAX_ I = {J}} ^ {N-(2 \ Sタイムズ[J] + [J])\) 誘導された式:maxsa[i] = max(maxsa[i+1], 2 \times s[i] + a[i])

そして、私たちがしたい\(N \)内の選択家族\(m個\)最大疲労値は、家族訪問することであるsum[m] + 2 * maxs[m]suma[m-1] + 2 * maxs[i]より大きな価値を。

次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100100;
int n, s[maxn], a[maxn], idx[maxn], suma[maxn], maxs[maxn], maxsa[maxn];
bool cmp(int i, int j) {
    return a[i] > a[j];
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> s[i];
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int i = 1; i <= n; i ++) idx[i] = i;
    sort(idx+1, idx+1+n, cmp);
    for (int i = 1; i <= n; i ++)
        suma[i] = suma[i-1] + a[idx[i]], maxs[i] = max(maxs[i-1], s[idx[i]]);
    for (int i = n; i >= 1; i --)
        maxsa[i] = max(maxsa[i+1], s[idx[i]] * 2 + a[idx[i]]);
    for (int i = 1; i <= n; i ++)
        cout << max(suma[i]+2*maxs[i], suma[i-1]+maxsa[i]) << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/codedecision/p/11782714.html