贪心——田忌赛马(HDU1052)

  • 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1052

  • 题意:田忌和王各有n匹马,每匹马有一个速度值,他俩赛马,赢者得200分,输者减200分,求田忌最多能得到多少分

  • 分析:贪心思路来想,我们先考虑完所有田忌能赢的情况,然后再用最小成本去输:

    • 先判断田忌最好的马是否能赛过王最好的马
    • 如若不行则考虑田忌最差的马是否能赛过王最好的马
    • 若还是不行则用田忌最差的马去赛王最好的马输掉一局(平局不算)
  • AC代码:

 /*************************************************************************
    > File Name: 1052.cpp
    > Author: Akira
    > Mail: qaq.febr2.qaq@gmail.com
    > Created Time: 2017年01月17日 星期二 20时49分05秒
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#include<vector>
#include<set>
#include<list>
#include<ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))

using namespace std;

#define MaxN 100000
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define EPS 1e-8
#define bug cout << 88888888 << endl;
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)

int n;
int A[1005];
int B[1005];
bool cmp(int a, int b)
{
    return a>b;
}
int main()
{
    while(~scanf("%d", &n) && n)
    {
        for(int i=0;i<n;i++) scanf("%d", &A[i]);
        for(int i=0;i<n;i++) scanf("%d", &B[i]);
        sort(A,A+n,cmp);
        sort(B,B+n,cmp);

        int win = 0;

        int Ts = 0,Qs = 0;
        int Te = n-1,Qe = n-1;

        while(n--)
        {
            if(A[Ts] > B[Qs])
            {
                Ts++;
                Qs++;
                win++;
            }
            else
            {
                if(A[Te] > B[Qe])
                {
                    Te--;
                    Qe--;
                    win++;
                }
                else if(A[Te]<B[Qs])
                {
                    Te--;
                    Qs++;
                    win--;
                }
            }
        }
        printf("%d\n", win*200);
    }
    return 0;
}
田忌赛马问题可以用矩阵博弈的方式来求解。假设田忌和齐王各有n匹马,马的速度不一样,田忌和齐王都知道各自马的速度,但不知道对方马的速度。现在要进行一场比赛,规则是田忌和齐王每次各选出一匹马进行比赛,速度快的获胜。每场比赛赢一分,平局不得分,输了不得分。比赛进行n场,求田忌最多能得多少分。 矩阵博弈的思路是构造一个n*n的矩阵,第i行第j列表示田忌用第i匹马与齐王用第j匹马比赛的得分。例如,第一行表示田忌用自己最快的马与齐王用不同的马比赛的得分,第二行表示田忌用自己第二快的马与齐王用不同的马比赛的得分,以此类推。 根据题意,构造比赛得分矩阵的方法如下: 1. 田忌用最快的马与齐王用最慢的马比赛,得分为1; 2. 田忌用第二快的马与齐王用第二慢的马比赛,得分为1; 3. 田忌用最慢的马与齐王用最快的马比赛,得分为0或-1。 注意,第三种情况得分为0或-1,是因为如果田忌用最慢的马与齐王用最快的马比赛,那么田忌必输,得分为-1;如果田忌用最慢的马与齐王用次慢的马比赛,那么田忌可能赢,得分为0或1。 根据上述方法可以构造比赛得分矩阵,然后使用线性规划的方法求解矩阵博弈问题。具体来说,可以将田忌和齐王的得分视为两个向量,将比赛得分矩阵视为一个矩阵,然后使用线性规划求解最大值问题。 以下是Matlab程序实现: ```matlab % 田忌赛马问题的矩阵博弈求解 n = 5; % 马匹数量 speeds = randperm(10, n); % 马的速度,随机生成 score_mat = zeros(n, n); % 得分矩阵 for i = 1:n for j = 1:n if i == j % 同一匹马不能比赛 continue; end if speeds(i) > speeds(j) % 田忌胜 score_mat(i, j) = 1; else % 田忌败 score_mat(i, j) = -1; end end end f = -ones(n, 1); % 目标函数 A = score_mat'; % 约束条件矩阵 b = ones(n, 1); % 约束条件向量 lb = zeros(n, 1); % 变量下界 ub = ones(n, 1); % 变量上界 options = optimset('Display', 'off'); % 不显示求解过程 x = linprog(f, A, b, [], [], lb, ub, options); % 求解线性规划问题 max_score = -sum(x); % 最大得分 disp(['田忌最多能得' num2str(max_score) '分']); ``` 该程序首先随机生成马的速度,然后根据上述方法构造比赛得分矩阵,最后使用Matlab内置函数linprog求解线性规划问题,得到田忌最多能得多少分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值