【算法实验四】--【动态规划】--田忌赛马(tian ji racing)

1047.田忌赛马(tian ji racing)

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

田忌与齐王赛马,双方各有n匹马参赛(n<=100),每场比赛赌注为1两黄金,现已知齐王与田忌的每匹马的速度,并且齐王肯定是按马的速度从快到慢出场,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金(输用负数表示)。
Tian Ji and the king play horse racing, both sides have n horse (n is no more the 100), every game a bet of 1 gold, now known king and Tian Ji each horse's speed, and the king is definitely on the horse speed from fast to slow, we want you to write a program to help Tian Ji his best result is win the number gold (lost express with the negative number).

 

输入

多个测例。
每个测例三行:第一行一个整数n,表示双方各有n匹马;第二行n个整数分别表示田忌的n匹马的速度;第三行n个整数分别表示齐王的n匹马的速度。
n=0表示输入结束。
A plurality of test cases.
Each test case of three lines: the first line contains an integer n, said the two sides each have n horse; second lines of N integers n Tian Ji horse speed; third lines of N integers King n horse speed.
N = 0 indicates the end of input.

 

输出

每行一个整数,田忌最多能赢多少两黄金。
how many gold the tian ji win

 

输入样例

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
3
20 20 10
20 20 10
0

 

输出样例

1
0
0
0

解析:说一下思路。这道题意味着田忌可以随意的排兵布阵,那么从最差的马开始。如果田忌最差的马能赢齐王最差的马,那么直接进行比较并且赢得场数加一,两匹马分别废掉不再使用。从低到高比,一旦有田忌的一匹马比不过同阶的齐王的马,立马将这匹马对阵齐王的目前剩余的最厉害的马,并且场数减一。如果两者目前对上的马相等,则有两种做法,第一种是平局不得分,第二种是放弃失一分,但是带走了齐王最厉害的马,为后面赢做准备。那么这里设计动态规划来实现此题。

首先我们从最慢的马开始,这里为了实现两头同时进行操作,设置两个参量 i 和 j ,i 表示田忌的第 i 匹马,j + i 表示齐王的马,这样是为了使得矩阵m[ i ] [ j ] 实现记录。代码如下:

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int MAX=1000;
int n;
int tian[50],qi[50];
int m[50][50];
int DP(int i,int j)
{
    if(i==-1)//所有的马都比完了
        return 0;
    else if(m[i][j]!=MAX)
        return m[i][j];
    else
    {
        if(tian[i]>qi[j+i])//如果田忌的目前最慢的马比齐王目前最慢的马快,两者相抵,得一分
            m[i][j]=DP(i-1,j)+1;
        else if(tian[i]<qi[j+i])//若没有齐王快,将其最快的马拉下水输一分
            m[i][j]=DP(i-1,j+1)-1;
        else
        {//相等的时候,可以选择
            int a=DP(i-1,j);//平局,不丢分
            int b=DP(i-1,j+1)+(tian[i]<qi[j]?-1:0);//刚掉其最快的马,输一分来保后面赢
            m[i][j]=max(a,b);//两者取其大值
        }
    }
    return m[i][j];
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        memset(tian,0,sizeof(tian));
        memset(qi,0,sizeof(qi));
        memset(m,0,sizeof(m));
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            m[i][j]=MAX;
        for(int i=0;i<n;i++)
            cin>>tian[i];
        for(int j=0;j<n;j++)
            cin>>qi[j];
        for(int i=0; i<n; i++)  //排序
        {
            for(int j=i; j<n; j++)
            {
                if(tian[i]<tian[j])
                {
                    swap(tian[i],tian[j]);
                }
                if(qi[i]<qi[j])
                {
                    swap(qi[i],qi[j]);
                }
            }
        }
        cout<<DP(n-1,0)<<endl;
    }
    return 0;
}

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值