4 条题解
-
23
当面临这样的问题时,我们可以采用贪心算法来解决。贪心算法是一种在每一步选择中都采取当前状态下最优决策的方法,从而希望最终能够达到全局最优解。在这个问题中,我们希望选择一部分人获得金币,另一部分人获得银币,使得总的硬币数量最大化。
首先,我们需要读取输入数据。第一行包含两个正整数x和y,分别表示需要选出的获得金币的人数和获得银币的人数。接下来的x+y行包含每个人的金币数量和银币数量。
然后,我们创建一个vector来保存每个人的金币和银币数量,并将其按照特定规则进行排序。根据提示,我们可以选择根据
ai-aj
的差值从大到小排序。这样可以确保我们优先选择ai
较大、aj
较小的人,使得选出的人中金币的总数量最大。排序完成后,我们从前x个人中选择获得金币的人员,从后y个人中选择获得银币的人员,并将他们各自的硬币数量累加得到总数量。
最后,输出总的硬币数量即可。
以下是整个算法的步骤:
- 读取输入数据,包括x、y和每个人的金币银币数量。
- 根据
ai-aj
的差值从大到小对人员进行排序。 - 选择前x个人获得金币,后y个人获得银币。
- 计算金币和银币的总数量,输出结果。
贪心算法的关键在于选择合适的排序规则,以及在每一步中做出当前状态下的最优选择。在这个问题中,选择根据
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)
双语言题解不易记得点赞!!! 点赞!!!点赞!!!
-
9
这道题关键在寻找贪心策略 目录: { 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
结语
题解时间制作成本相当高,别忘点赞支持一下~
-
1
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
- 上传者