加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

贪心算法--田忌赛马问题

(2010-12-11 15:37:24)
标签:

马来

齐王

田忌赛马

贪心算法

it

分类: Algorithm

题目描述:

你一定听过田忌赛马的故事吧?
如果3匹马变成1000匹,齐王仍然让他的马按从优到劣的顺序出赛,田忌可以按任意顺序选择他的赛马出赛。赢一局,田忌可以得到200两银子,输一局,田忌就要输掉200两银子,平局的话不输不赢。
请问田忌最多能赢多少银子?

 

关于输入
输入包含多组测试数据.
每组测试数据的第一行是一个整数n(1<=n<=1000),表示田忌和齐王都拥有n匹马。接下来一行是n个整数,表示田忌的马的速度,下一行也是n个整数,表示齐王的马的速度。
输入的最后以一个0表示结束。

 

关于输出
对每组数据,输出一个整数,表示田忌至多可以赢多少银子,如果田忌赢不了,就输出一个负数,表示田忌最少要输多少银子。

 

解题思路:

算法可以用DP,或者给每匹马连线赋权变为二分图最佳匹配,还有就是贪心了。
1.当田忌最慢的马比齐王最慢的马快,赢一场先
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场
3.当田忌最快的马比齐王最快的马快时,赢一场先。
4.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场。
5.当田忌最快的马和齐王最快的马相等时,拿最慢的马来和齐王最快的马比.

田忌赛马贪心的正确性证明。

先说简单状况下的证明:
1.当田忌最慢的马比齐王最慢的马快,赢一场先。因为始终要赢齐王最慢的马,不如用最没用的马来赢它。
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场。因为田忌最慢的马始终要输的,不如用它来消耗齐王最有用的马。
3.当田忌最慢的和齐王最慢的马慢相等时,分4和5讨论。
4.当田忌最快的马比齐王最快的马快时,赢一场先。因为最快的马的用途就是来赢别人快的马,别人慢的马什么马都能赢。
5.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场,因为反正要输一场,不如拿最没用的马输。
6.当田忌最快的马和齐王最快的马相等时,这就要展开讨论了,贪心方法是,拿最慢的马来和齐王最快的马比.
前面的证明像公理样的,大家一看都能认同的,没有异议的,就不细说了。


证明:田忌最快的马和齐王最快的马相等时拿最慢的马来和齐王最快的马比有最优解。

可以举例来证明,比较容易理解。

 

C++程序代码如下:

#include <iostream>
#include <vector>

using namespace std;


void change(int &a, int &b)
{
 int temp;
 temp = a;
 a = b;
 b = temp;
}

void quickSort(int* a, int l, int u)
{
 int i, m;
 if (l >= u) return;
 m = l;
 for (i = l + 1; i <= u; i++)
  if (a[i] > a[l])
   change(a[++m], a[i]);

 change(a[l], a[m]);

 quickSort(a, l, m - 1);
 quickSort(a, m + 1, u);
}

int main()
{
 vector<int> result;
 vector<int> ra;
 vector<int> rb;
 int num;
 int* a;
 int* b;
 while (cin>>num)
 {
  if (num == 0)
   break;
  a = new int[num];
  b = new int[num];
  for (int i = 0; i < num; i++)
   cin>>a[i];
  for (int i = 0; i < num; i++)
   cin>>b[i];

  quickSort(a, 0, num-1);
  quickSort(b, 0, num-1);

  int win = 0;
  int fail = 0;
  int draw = 0;
  int ib = 0, jb = 0;
  int ie = num - 1, je = num - 1;

  while (ib <= ie)
  {
   if (a[ie] > b[je])
   {
    win++;
    ie--;
    je--;
   }else if (a[ie] < b[je])
   {
    fail++;
    ie--;
    jb++;
   }else
   {
    if (a[ib] > b[jb])
    {
     win++;
     ib++;
     jb++;
    }else
    {
     if (a[ie] < b[jb])
      fail++;
     ie--;
     jb++;
    }
   }
  }
  result.push_back(200*(win - fail));
  
 }
 for (size_t i = 0; i != result.size(); i++)
 {
  cout<<result[i]<<endl;
 }

 return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有