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;
}