4 条题解

  • 23
    @ 2023-7-27 19:56:12

    当面临这样的问题时,我们可以采用贪心算法来解决。贪心算法是一种在每一步选择中都采取当前状态下最优决策的方法,从而希望最终能够达到全局最优解。在这个问题中,我们希望选择一部分人获得金币,另一部分人获得银币,使得总的硬币数量最大化。

    首先,我们需要读取输入数据。第一行包含两个正整数x和y,分别表示需要选出的获得金币的人数和获得银币的人数。接下来的x+y行包含每个人的金币数量和银币数量。

    然后,我们创建一个vector来保存每个人的金币和银币数量,并将其按照特定规则进行排序。根据提示,我们可以选择根据 ai-aj 的差值从大到小排序。这样可以确保我们优先选择 ai 较大、aj 较小的人,使得选出的人中金币的总数量最大。

    排序完成后,我们从前x个人中选择获得金币的人员,从后y个人中选择获得银币的人员,并将他们各自的硬币数量累加得到总数量。

    最后,输出总的硬币数量即可。

    以下是整个算法的步骤:

    1. 读取输入数据,包括x、y和每个人的金币银币数量。
    2. 根据 ai-aj 的差值从大到小对人员进行排序。
    3. 选择前x个人获得金币,后y个人获得银币。
    4. 计算金币和银币的总数量,输出结果。

    贪心算法的关键在于选择合适的排序规则,以及在每一步中做出当前状态下的最优选择。在这个问题中,选择根据 ai-aj 的差值从大到小排序,是一个很好的策略,能够得到最优解。 C++:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
        int x, y;
        cin >> x >> y;
    
        int n = x + y;
        vector<pair<int, int>> coins(n);
    
        for (int i = 0; i < n; i++) {
            cin >> coins[i].first >> coins[i].second;
        }
    
        sort(coins.begin(), coins.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
            return a.first - a.second > b.first - b.second;
        });
    
        int totalCoins = 0;
    
        for (int i = 0; i < x; i++) {
            totalCoins += coins[i].first;
        }
    
        for (int i = x; i < n; i++) {
            totalCoins += coins[i].second;
        }
    
        cout << totalCoins << endl;
    
        return 0;
    }
    

    PY:

    x, y = map(int, input().split())
    people = []
    
    for _ in range(x+y):
        gold, silver = map(int, input().split())
        people.append((gold, silver))
    
    people.sort(key=lambda p: p[0] - p[1], reverse=True)
    
    total_coins = sum(p[0] for p in people[:x]) + sum(p[1] for p in people[x:])
    
    print(total_coins)
    

    双语言题解不易记得点赞!!! 点赞!!!点赞!!!

    • @ 2023-7-28 16:03:34

      你干脆所有都写了吧 Py着实没什么用

    • @ 2023-7-28 20:13:42

      你这也不行啊,两个语言都是错的,上我的:

      #include<bits/stdc++.h>
      using namespace std;
      struct T
      {
      int a, b;
      } c[100005];
      bool cmp(T x,T y)
      {
      return x.a -x.b > y.a -y.b;
      }
      int main()
      {
      int x, y, n, sum = 0;
      cin >> x >> y;
      n = x + y;
      for (int i = 1; i <= n; i++)
      {
      cin >> c[i].a >> c[i].b;
      }
      sort(c + 1,c + n + 1, cmp);
      for (int i = 1; i <= x; i++)
      {
      sum += c[i].a;
      }
      for (int i = x + 1; i <= n; i++)
      {
      sum += c[i].b;
      }
      cout << sum;
      return 0;
      }
      
    • @ 2023-10-7 21:31:14

      @ 现代人这么不喜欢缩进吗? 看看人家@王浩冉 (hetao1701187) 至少会缩进……

    • @ 2024-5-1 14:00:45

      @

      罗子曜(hetao6787909) (hetao6787909) 你和王浩冉是有什么深仇大恨吗,天天针对他。

  • 9
    @ 2024-2-23 9:42:10

    这道题关键在寻找贪心策略 目录: { 1.题目回顾 2.解题思路 3.代码实现 4.结语 } 进入正题

    题目回顾

    P1065.硬币数量

    题目描述

    有x+y个人,第i个人有ai枚金币,bi枚银币。从中选出x个人获得其金币,剩下y个人获得其银币,在不重复选某个人的情况下,最大化获得硬币的总数。

    输入格式

    第1行是两个正整数x,y; 第2~n+1行,每行两个正整数,分别表示金币和银币的数量。

    输出格式

    输出1行1个整数,为最终获得的硬币的总数量。

    解题思路

    本题总共有x+y个人,每个人都得拿硬币,不拿金币就拿银币, 但你得讲人性,不能全拿走 这时你想多赚点,一方面要金币多,一方面要银币多,相互干扰 此时,对于一个人,有两种状态 只剩金币或只剩银币,两者中的较小值是一定拿走的,所以此时的币子数量为|a-b|,我们可以先只考虑拿金币的人选,这样其余y个人就拿他的银币即可,这样我们就制定出来正确的贪心策略

    bool cmp(Coin q,Coin e)
    {
    	return q.a - q.b > e.a - e.b;
    }
    
    代码实现
    #include <bits/stdc++.h>
    using namespace std;
    struct Coin
    {
    	int a,b;
    }s[100005];
    bool cmp(Coin q,Coin e)
    {
    	return q.a - q.b > e.a - e.b;
    }
    int main() 
    {
    	int x,y;
    	cin >> x >> y;
    	for (int i = 1;i <= x + y;i++)
    	{
    		cin >> s[i].a >> s[i].b;
    	}
    	int ans = 0;
    	sort(s+1,s+x+y+1,cmp);
    	for (int i = 1;i <= x;i++)
    	{
    		ans+=s[i].a;
    	}
    	for (int i = x+1;i <= x+y;i++)
    	{
    		ans+=s[i].b;
    	}
    	cout << ans;
    	return 0;
    }//代码已AC
    
    结语

    题解时间制作成本相当高,别忘点赞支持一下~

    • 7
      @ 2023-7-6 16:28:39

      选出第i和第j两个人,获取i的金币和j的银币可表示为ai+bj,若交换两人位置则获取的硬币数量为aj+bi,考虑让i排在j前更优,则需要满足ai+bj>bi+aj,移项可得排序规则:ai-aj>bi-bj

      • 1
        @ 2023-7-28 13:03:09

        ai+bj>bi+aj是排序的方法 最短的代码:

        #include <bits/stdc++.h>
        int main(void) {
            int x, y, sum = 0;
            std::cin >> x >> y;
            std::vector<std::pair<int, int> > coins(x + y);
            for (int i = 0; i < x + y; i++)
                std::cin >> coins[i].first >> coins[i].second;
            std::sort(coins.begin(), coins.end(), [](std::pair<int, int> x, std::pair<int, int> y) {return x.first - x.second > y.first - y.second; });
            for (int i = 0; i < x; i++)
                sum += coins[i].first;
            for (int i = x; i < x + y; i++)
                sum += coins[i].second;
            std::cout << sum;
            return 0;
        }
        
        • 1

        信息

        ID
        260
        时间
        1000ms
        内存
        256MiB
        难度
        3
        标签
        (无)
        递交数
        721
        已通过
        386
        上传者