AtCoder题解——Beginner Contest 167——B - Easy Linear Programming

题目相关

题目链接

AtCoder,https://atcoder.jp/contests/abc167/tasks/abc167_c。

Problem Statement

We have A cards, each of which has an integer 1 written on it. Similarly, we also have B cards with 0s and C cards with −1s.

We will pick up K among these cards. What is the maximum possible sum of the numbers written on the cards chosen?

Input

Input is given from Standard Input in the following format:

A B C K

Output

Print the maximum possible sum of the numbers written on the cards chosen.

Samples1

Sample Input 1

2 1 1 3

Sample Output 1

2

Explaination

Consider picking up two cards with 1s and one card with a 0. In this case, the sum of the numbers written on the cards is 2, which is the maximum possible value.

Samples2

Sample Input 2

1 2 3 4

Sample Output 2

0

Samples3

Sample Input 3

2000000000 0 0 2000000000

Sample Output 3

2000000000

Constraints

  • All values in input are integers.
  • 0 ≤ A,B,C
  • 1 ≤ K ≤ A+B+C ≤ 2×10^9

题解报告

本题含义

我们有 A 张值为 1 的牌,B 张值为 0 的牌,C 张值为 -1 的牌。让我们从中选出 K 张牌,要求这 K 张牌的总和最大。

样例数据分析

本题是一个非常简单的数学题数学题。题目是要求选出的牌总和最大,因此我们可以使用贪心算法。

样例数据1

输入数据为:2 1 1 3。我们有 2 张值为 1 的牌,1 张值为 0 的牌,1 张值为 -1 的牌,从中选出 3 张牌,要求总和最大。

根据贪心的思路,我们需要选出 3 张牌,先选出 2 张值为 1 的牌;再选出 1 张值为 0 的牌。这样合计 3 张牌,总和为 2*1+1*0=2。

样例数据2

输入数据为:1 2 3 4。我们有 1 张值为 1 的牌,2 张值为 0 的牌,3 张值为 -1 的牌,从中选出 4 张牌,要求总和最大。

根据贪心的思路,我们需要选出 4 张牌,先选出 1 张值为 1 的牌;再选出 2 张值为 0 的牌;再选出 1 张值为 -1 的牌。这样合计 4 张牌,总和为 1*1+2*0+1*(-1)=0。

样例数据3

输入数据为:2000000000 0 0 2000000000。我们有 2000000000 张值为 1 的牌,0 张值为 0 的牌,0 张值为 -1 的牌,从中选出 2000000000 张牌,要求总和最大。

根据贪心的思路,我们需要选出 2000000000 张牌,先选出 2000000000 张值为 1 的牌。这样合计 2000000000 张牌,总和为 2000000000*1=2000000000。

算法设计

可以使用贪心算法,也可以直接使用数学公式进行计算。下面我们分类讨论一下输出的可能性,好比分段函数。

1、当 K ≤ A 的时候,我们选择 K 张值为 1 的牌,结果的最大值是 K。

2、当 A < K ≤ A+B 的时候,我们选择 A 张值为 1 的牌,再选择 A+B-K 张值为 0 的牌,结果的最大值是 A。

3、当 A+B < K 的时候,首先我们先选择 A 张值为 1 的牌,再选择 B 张值为 0 的牌,再选择 K-(A+B) 张值为 -1 的牌,结果的最大值是 A+(K-(A+B))*(-1)=A-K+(A+B)=2A-K+B。

数据范围分析

根据题目给出的数据范围是 [1, 2*10^9],看上去第一反应是 int 可以满足要求。但是我们在算法设计的时候,当 A+B < K 的时候,有一个计算公式 2A-K+B,这个计算公式的范围是多少?

1、最小值是多少?自然是 A 和 B 都是 0,K 为最大数据 2*10^9,因此最小值为 -2000000000。

2、最大值是多少?应该是 K=2*10^9,A=2*10^9-1,B=0的时候,因此最大值为 4*10^9-2-2*10^9=2*10^9-1。

看上去没有超过 int 的范围,如果使用 int 来表示,在计算 2A 的时候,出现了数据越界。

所以本题安全的做法数据用 long long 来表示即可。

AC 参考代码

#include 
using namespace std;
int main() {
    long long a,b,c,k;
    cin>>a>>b>>c>>k;

    if (k<=a+b) {
        cout << min(a,k) << endl;
    } else {
        cout << 2*a-k+b << endl;
    }

    return 0;
}

 

P.S.

道歉,拷贝的时候竟然题目写错了。丢人。

你可能感兴趣的:(OJ题解,#,AtCoder题解)