P1650 田忌赛马
P1650 田忌赛马
题目
我国历史上有个著名的故事: 那是在
田忌很沮丧,直到他遇到了著名的军师――孙膑。田忌采用了孙膑的计策之后,三场比赛下来,轻松而优雅地赢了齐王
如果不止三匹马怎么办?这个问题很显然可以转化成一个二分图最佳匹配的问题。把田忌的马放左边,把齐王的马放右边。田忌的马 A 和齐王的 B 之间,如果田忌的马胜,则连一条权为
输入
第一行一个整数
输出
仅一行,一个整数,表示田忌最大能得到多少银币。
样例
输入
3
92 83 71
95 87 74
输出
200
提示
数据规模与约定
- 对于
的数据, ; - 对于
的数据, ; - 对于
的数据, 。
思路
不妨用贪心思想来分析一下。因为田忌掌握有比赛的“主动权”,他总是根据齐王所出的马来分配自己的马,所以这里不妨认为齐王的出马顺序是按马的速度从高到低出的。由这样的假设,归纳如下贪心策略。
-
如果田忌目前的最快马快于齐王目前的最快马,则两者比。如果田忌的最快马慢于齐王的最快马,则用田忌的最慢马与齐王的最快马比(减少损失)。以此类推。
-
如果田忌的最快马和齐王的最快马相等,分为以下两种情况:(1)若田忌的最慢马快于齐王的最慢马,则两者比(贪心思想:能赢就赢)。(2)若田忌的最慢马慢于齐王的最慢马或者相等,用田忌的最慢马与齐王的最快马比(贪心思想:贡献最大)。
这里比较难理解的“田忌的最快马和齐王的最快马相等,两队中最慢马也相等”的情况,运用反证法思想去理解,假设“用田忌的最慢马与齐王的最快马比”是错误的,则如果齐王马的速度分别是
代码
#include <bits/stdc++.h>
using namespace std;
int a[2010], b[2010], ans, n, la = 1, lb = 1, ra, rb;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ )
scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ )
scanf("%d", &b[i]);
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
ra = rb = n;
for (int i = 1; i <= n; i ++ )
{
if (a[ra] > b[rb])
{
ans += 200;
ra --;
rb --;
}
else if (a[ra] < b[rb])
{
ans -= 200;
la ++;
rb --;
}
else if (a[la] > b[lb]) // 两队最快的相等
{
ans += 200;
la ++;
lb ++;
}
else // 用田忌的最慢马与齐王的最快马比
{
if (a[la] < b[rb])
ans -= 200;
la ++;
rb --;
}
}
printf("%d", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)