田忌赛马(贪心)

思路完全偏了,百思不得其解,看了题解。
题意:田忌赛马。大王有n匹马,田忌也有n匹马。田忌每赢一局得200银币,输一局-200银币,平局钱数不变。那么问题来了,田忌最多能获得多少银币?
分析:
一.策略
首先是每次都用田忌最快的马与大王最快的马比
1.如果田忌最快的马快,就用田忌最快的马,赢了大王最快的马。
2.如果大王最快的马快,就用田忌最慢的马输给大王最快的马。
3.如果是平局需要分类讨论。
    a.当大王最慢的马,比田忌最慢的马慢,此时田忌最慢的马与大王最慢的马比。
    b.当大王最慢的马,比田忌最慢的马快,此时田忌最慢的马与大王最快的马比。
    c.当大王最慢的马与田忌最慢的马一样,此时田忌最慢的马与大王最快的马比。
二.算法证明
1.设大王最快的马K,田忌最快的马T。且田忌的马快。T > K假设不是用大王最快的马,与田忌最快的马比。因为田忌最快的马,不与大王最快的马比,就一定要和大王别的马比。那么设大王与t相比的马为k,显然 k <= K,设田忌的与K相比的马为t,显然t <= T,。
    a.k > t。T > K >= k > t。原来的两局TK比,kt比,田忌赢一局,输一局。现在的两局Tk比,Kt比,同样。不增不减
    b.k = t。T > K >= k = t。原来的两局TK比,kt比,田忌赢一局,平一局。现在的两局Tk比,Kt比,田忌赢一局,平或输一局,不如原来。
    c.k < t。T > K >= k < t <= T。原来的两局TK比,tk比,田忌赢一局,赢一局。现在的两局Tk比,Kt比不一定,田忌赢一局,一局不定,不如原来
    可证,如此取是合适的
2.大王最快的马一定赢,所以要用田忌最慢的马来输。
3.大王与田忌最快的马平局了,此时就要看最慢的马们(???)
    a.田忌最慢的马比大王最慢的马快,证明同1
    b.田忌最慢的马比大王最慢的马慢,所以田忌最慢的马,比大王所有的马都慢。及此马必输,就让此马与最快的比
    c.平局的情况。如果让最快的马与最快的比,最慢的与最慢的比,结果是零。如果让田忌最慢的与大王最快的比,然后用只比大王最慢的马大一点的马与大王最慢的比,这样就保留了田忌最快的马。
 
代码:
/**错误点:1贪心错了,应该是每次用田忌最快的马,与齐王最快的马比,如果田忌的快,赢之,如果齐王的快则田忌用最慢的马赫他玩儿
如果平局,此时要进行特殊处理:
2简单的认为平局打还是不打是不正确的**/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int t[1005],k[1005];
bool idx[1005];
bool cmp(int a,int b)
{
    return a > b;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    while(1)
    {
        scanf("%d",&n);
        if(n == 0)
            break;
        memset(idx,false,sizeof(idx));
        int ans = 0;
        for(int i = 0; i < n; i ++)
        {
            scanf("%d",&t[i]);
        }
        for(int i = 0; i < n; i ++)
        {
            scanf("%d",&k[i]);
        }
        sort(t, t + n,cmp);
        sort(k, k +n,cmp);

        int tk = 0,tm = n - 1,kk = 0,km = n - 1;//tk田忌最快的,tm田忌最慢的。kk国王最快的,km国王最慢的
        while(n --)
        {
            if(t[tk] > k[kk])
            {
                tk ++;
                kk ++;
                ans ++;
            }
            else if(t[tk] < k[kk])
            {
                tm --;
                kk ++;
                ans --;
            }
            else
            {
                if(t[tm] <= k[km])
                {
                    if(t[tm] < k[kk])
                    {
                        ans --;
                    }

                    tm --;
                    kk ++;

                }
                else
                {
                    tm --;
                    km --;
                    ans ++;
                }
            }
        }
        printf("%d\n",ans * 200);
    }
    return 0;
}

<span style="font-size:18px;"></span> 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值