泡泡堂(田忌赛马一类的贪心问题)

Posted mowanying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泡泡堂(田忌赛马一类的贪心问题)相关的知识,希望对你有一定的参考价值。

P2587 [ZJOI2008]泡泡堂

分析:

对于这种通过合理分配来获得较高分的问题,有dp和贪心两种方法。

贪心在考场上写有点悬,最好对拍来及时检查贪心策略是否正确。

这道题的贪心策略是:(序号有优先顺序)

1. 弱的赢弱的

2. 强的赢强的

3. 两个都不行,就让弱的送强的(同时判断一下能否平局)

同时,我方最坏就是对方最优,总的减去对方最优即可。

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ri register int
#define N 100005
int n,a[N],b[N];
int work()
{
    int l1=1,r1=n,l2=1,r2=n,ans=0;
    //贪心策略:如果最弱的能赢最弱的,就直接赢,否则就考虑最强的能不能赢最强的,再不行才考虑用最弱的送给最强的,记得判断一下是否能平局 
    while(l1<=r1 && l2<=r2){
        if(a[l1]>b[l2]) ans+=2,l1++,l2++;
        else if(a[r1]>b[r2]) ans+=2,r2--,r1--;
        else ans+=(a[l1]==b[r2]),l1++,r2--;
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(ri i=1;i<=n;++i) scanf("%d",&a[i]);//me
    for(ri i=1;i<=n;++i) scanf("%d",&b[i]);
    sort(a+1,a+1+n); sort(b+1,b+1+n);
    int anss=work();
    swap(a,b);
    printf("%d %d",anss,2*n-work());
}
/*
2
1
3
2
4

8
4 1 0 7 8 3 5 5 
4 8 0 3 4 2 5 7 
4
1 2 2 9 
9 3 2 4 
3
2 9 8 
4 7 2 
*/
View Code

P1650 田忌赛马

分析:

这道题和上一道一样,策略同样是:弱打弱,强打强,弱送强。

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ri register int
#define N 100005
int n,a[N],b[N];
void work()
{
    int l1=1,r1=n,l2=1,r2=n,ans=0;
    for(ri i=1;i<=n;++i){
        if(a[l1]>b[l2]) ans++,l1++,l2++;
        else if(a[r1]>b[r2]) ans++,r1--,r2--;
        else {
            if(a[l1]>b[r2]) ans++;
            else if(a[l1]<b[r2])ans--;
            l1++; r2--;
        }
    }
    printf("%d
",ans*200);
}
int main()
{
    scanf("%d",&n);
    for(ri i=1;i<=n;++i) scanf("%d",&a[i]);//me
    for(ri i=1;i<=n;++i) scanf("%d",&b[i]);
    sort(a+1,a+1+n); sort(b+1,b+1+n);
    work();
    return 0;
}
/*
WA: 
5
5 1 2 8 3 
5 0 6 5 2 
*/
View Code

l, r 指针不要打反了。。。

以上是关于泡泡堂(田忌赛马一类的贪心问题)的主要内容,如果未能解决你的问题,请参考以下文章

[ZJOI2008]泡泡堂

[luoguP2587] [ZJOI2008]泡泡堂(贪心)

POJ 2287 田忌赛马 贪心算法

刷题向》关于一道奇怪的贪心(田忌赛马)BZOJ1034

贪心1:从田忌赛马说起

[Poj2287][Tyvj1048]田忌赛马 (贪心+DP)