洛谷P1650 田忌赛马【DP+贪心】【绿】

Date:2022.03.22
题目描述
我国历史上有个著名的故事: 那是在2300年以前。齐国的大将军田忌喜欢赛马。他经常和齐王赛马。他和齐王都有三匹马:常规马,上级马,超级马。一共赛三局,每局的胜者可以从负者这里取得200银币。每匹马只能用一次。齐王的马好,同等级的马,齐王的总是比田忌的要好一点。于是每次和齐王赛马,田忌总会输600银币。
田忌很沮丧,直到他遇到了著名的军师――孙膑。田忌采用了孙膑的计策之后,三场比赛下来,轻松而优雅地赢了齐王200银币。这实在是个很简单的计策。由于齐王总是先出最好的马,再出次好的,所以田忌用常规马对齐王的超级马,用自己的超级马对齐王的上级马,用自己的上级马对齐王的常规马,以两胜一负的战绩赢得200银币。实在很简单。
如果不止三匹马怎么办?这个问题很显然可以转化成一个二分图最佳匹配的问题。把田忌的马放左边,把齐王的马放右边。田忌的马A和齐王的B之间,如果田忌的马胜,则连一条权为200的边;如果平局,则连一条权为0的边;如果输,则连一条权为-200的边……如果你不会求最佳匹配,用最小费用最大流也可以啊。 然而,赛马问题是一种特殊的二分图最佳匹配的问题,上面的算法过于先进了,简直是杀鸡用牛刀。现在,就请你设计一个简单的算法解决这个问题。
输入格式
第一行一个整数n,表示他们各有几匹马(两人拥有的马的数目相同)。第二行n个整数,每个整数都代表田忌的某匹马的速度值(0 <= 速度值<= 100)。第三行n个整数,描述齐王的马的速度值。两马相遇,根据速度值的大小就可以知道哪匹马会胜出。如果速度值相同,则和局,谁也不拿钱。
【数据规模】
对于20%的数据,1<=N<=65;
对于40%的数据,1<=N<=250;
对于100%的数据,1<=N<=2000。
输出格式
仅一行,一个整数,表示田忌最大能得到多少银币。
输入输出样例
输入 #1复制
3
92 83 71
95 87 74
输出 #1复制
200

思路:每次都要冲着赢去,因此田忌先用最快马比较,快则先赢下这一句;慢则用目前剩下的最慢马输,以最好地保留实力;平局不太好说,因此dp的主要是平局情况。此外,注意最大值可能为负,注意初始化边界。
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int n,m,f[N][N],a[N],b[N],sum[N];
int main()
{
   
   
    cin
P1650 田忌赛马平台上的一道算法题目,以下是关于它的详细信息: ### 题目描述 这是一道以经典故事“田忌赛马”为背景的算法题。在该题中,田忌和齐王各有 $n$ 匹马参赛,每匹马都有一个固定的速度。比赛共进行 $n$ 场,每场比赛双方各出一匹马,速度快的马获胜,获胜方从输方得到 200 银币,若速度相同则双方均不损失也不获利。目标是让田忌在这 $n$ 场比赛中获得最多的银币。 ### 输入格式 第一行输入一个整数 $n$,代表双方马的数量。 第二行输入 $n$ 个整数,为田忌的马的速度。 第三行输入 $n$ 个整数,为齐王的马的速度。 ### 输出格式 输出一个整数,即田忌最多能获得的银币数。 ### 解题思路 该题可以使用贪心算法来解决,其核心思路如下: - 对田忌和齐王的马的速度分别进行排序。 - 比较双方最快的马: - 若田忌最快的马比齐王最快的马快,就让这两匹马比赛,田忌获胜。 - 若田忌最快的马比齐王最快的马慢,用田忌最慢的马和齐王最快的马比赛,田忌失败。 - 若二者速度相同,比较双方最慢的马: - 若田忌最慢的马比齐王最慢的马快,让这两匹马比赛,田忌获胜。 - 若田忌最慢的马比齐王最慢的马慢或相同,用田忌最慢的马和齐王最快的马比赛。 ### 示例代码(Python) ```python n = int(input()) tianji = sorted(map(int, input().split())) qiwang = sorted(map(int, input().split())) left_tian, right_tian = 0, n - 1 left_qi, right_qi = 0, n - 1 win = 0 for _ in range(n): if tianji[right_tian] > qiwang[right_qi]: win += 1 right_tian -= 1 right_qi -= 1 elif tianji[right_tian] < qiwang[right_qi]: win -= 1 left_tian += 1 right_qi -= 1 else: if tianji[left_tian] > qiwang[left_qi]: win += 1 left_tian += 1 left_qi += 1 else: if tianji[left_tian] < qiwang[right_qi]: win -= 1 left_tian += 1 right_qi -= 1 print(win * 200) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值