[Basic Course on Acwing Algorithm] Chapter 6 Greedy-Pushing the Formula-125. The Acrobatic Cow

125. The acrobatic cow

Topic: 125. Acrobatic Cow - AcWing Question Bank

Understanding the meaning of the question: Sort the cows so that the maximum risk value is the smallest, that is, get a sorting that can reduce the maximum risk value.


I have a wrong idea about this question:

My thoughts:

Your task is to rank the cows so that the maximum risk value of all cows is as small as possible.

  1. The risk value of each situationThe maximum valueis the risk value of the lowest cow

  2. So the bottom cow must be selected. Under a certain selection plan, the risk value of the bottom cow is smaller than the risk value of other cows as the bottom cow , this minimum value is the result

  3. Risk value = w1 + ... + wn-1 - Sn = ∑Wi - Wn - Sn = ∑Wi - (Wn + Sn)

    It can be seen that the cow with the largest sum of w and s should be selected and placed at the bottom.

prove:

  1. The first sentence can prove:

    Proof by contradiction: If the risk value of a cow in the middle is the maximum, you can exchange it to the bottom, and the risk value will continue to increase. Therefore, the risk value of the cow at the bottom is the maximum.

My idea can be debugged, but it cannot pass ac. I haven’t figured out what is going on. At present, I think I should find the maximum value first and fix the maximum value at the bottom. In fact, the requirement of the question is that the risk needs to be The value is reduced, and then the maximum value is found. At this time, the maximum value may appear in the middle layer of Niuniu!! t There is a problem with understanding the meaning of the question.

code

#include <iostream>
#include <algorithm>
//贪心 推公式 耍杂技的牛 这个思路可以通过调试, 但是不能ac, 题意的理解有问题
using namespace std;

const int N = 50010;

int n;//牛的数量
int w[N];
int s[N];

int main() {
    scanf("%d", &n);//输入牛数量
    int max_sum = 0;//w和s之和
    int sum = 0;//所有牛的重量的和
    for (int i = 1; i <= n; i++)
        scanf("%d %d", &w[i], &s[i]), sum += w[i], max_sum = max(max_sum, w[i] + s[i]);

    int res = -2e9;//风险值结果
    //把max_sum放最底下就是对的
    res= sum - max_sum;//∑Wi - (Sn + Wn)

    printf("%d\n", res);

    return 0;
}

Correct thinking:

  1. According to the order of Wi+Si from small to large, the largest risk coefficient must be the smallest, and the risk values ​​​​in this sequence are sorted.

prove:

  1. Greedy answer (one solution) >= optimal solution ans, established

  2. The answer obtained by greedy <= optimal solution.

    Assume that the optimal solution is not sorted from small to large according to Wi+Si, that is, there are two adjacent cows such that wi + si > wi+1 + si+1

    Swapping these two cows, we get:

    cow in position i Cow at position i+1
    pre-exchange risk w1 + ... + w(i-1) - si w1 + ...+ wi - s(i+1)
    After exchange w1 + ... + w(i-1) - s(i+1) w1+...+ w(i-1) + w(i+1) - si

    cow in position i Cow at position i+1
    pre-exchange risk - and wi - s(i+1)
    After exchange - s(i+1) w(i+1) - si

    Add si + s(i+1) to both

    cow in position i Cow at position i+1
    pre-exchange risk s(i+1) said + to
    After exchange and w(i+1) + s(i+1)

    wi + si > si, wi + si > w(i+1) + s(i+1) Therefore, the maximum value of the risk value of the two numbers becomes smaller after the exchange

    So as long as there is reverse order, after several exchanges, it can be exchanged into the sum of the two numbers, sorted from small to large.

Code:

#include <iostream>
#include <algorithm>
//贪心 推公式 耍杂技的牛
using namespace std;

typedef pair<int, int> PII;//要整体排序, j就把两个数组整体存到pair

const int N = 50010;

int n;//牛的数量
//int w[N], s[N];
PII cow[N];//w和s组合起来

int main()
{
    scanf("%d", &n);//输入牛数量

    for (int i = 0; i < n; i++) {
        int w, s;//pair的两个参数
        scanf("%d%d", &w, &s);
        cow[i] = {w + s, w};//
    }

    //排序
    sort(cow, cow + n);//pair排序, 按值从小到大


    int res = -2e9, sum = 0;//所有牛的重量的和
    for (int i = 0; i < n; i++)
    {
        int w = cow[i].second, s = cow[i].first - w;
        res = max(res, sum - s);
        sum += w;
    }

    printf("%d\n", res);

    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_65293439/article/details/128473995