首页 > 代码库 > UvaLive 6441 Horrible Quiz 贪心

UvaLive 6441 Horrible Quiz 贪心

链接:http://vjudge.net/problem/viewProblem.action?id=47588

题意:刚开始有15000的积分,有N道题,对于每道题,有Ci%的概率答对,有Wi%的概率答错,(100-Ci-Wi)%的概率会选择提供的答案,可以提供的答案中最多可以提供M个错的答案,剩下的都必须是对的,答错的时候,积分*-1,答对的时候积分不变,问可以选择的M题,使可以得到的分数最低的期望是多少。

思路:公式中Ci,Wi分别表示正确和错误的概率(Ci+Wi=1)

对于提供错误答案和正确答案的情况下答对题的概率是不同的,所以分别记录。 因为要使期望尽可能的小,所以最优的情况是尽可能使积分是负数,并且是期望的绝对值尽可能大,如果期望不能是负数,那么就要使积分的绝对值尽可能小。根据提供错误答案与提供正确答案获得的期望之比来进行决定提供错误答案的题和提供正确答案的题,即可获得最优解。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define eps 1e-8
using namespace std;
struct point
{
    int a,b;
    double ac,wa;
} aa[1255],zz[1255],ff[1255],cc[1255];
bool cmp1(point a,point b)
{
    return fabs(a.wa*b.ac)<fabs(b.wa*a.ac);
}
bool cmp2(point a,point b)
{
    return fabs(a.wa*b.ac)>fabs(b.wa*a.ac);
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int ii=1; ii<=T; ii++)
    {
        double ans=15000;
        int tw=0,tt=0,tb0=0;
        int tot,wrong,top1=0;
        scanf("%d%d",&tot,&wrong);
        for(int i=0; i<tot; i++)
            scanf("%d",&aa[i].a);
        for(int i=0; i<tot; i++)
            scanf("%d",&aa[i].b);
        printf("Case #%d: ",ii);
        for(int i=0; i<tot; i++)
        {
            aa[i].ac=(double)((100-aa[i].b)*2-100);
            aa[i].ac/=100.0;
            aa[i].wa=(double)(aa[i].a*2-100);
            aa[i].wa/=100.0;
            if(aa[i].ac<0)
            {
                tw++;
                ff[top1++]=aa[i];
            }
            else if(aa[i].wa>=0)
            {
                ff[top1++]=aa[i];
            }
            else
            {
                cc[tt++]=aa[i];
            }
            if(aa[i].ac==0)
                tb0++;
            if(aa[i].wa==0)
                tb0++;
        }
        if(wrong==0)
        {
            for(int i=0; i<tot; i++)
            {
                ans*=aa[i].ac;
            }
            if (fabs(ans)<eps)
                ans=0;
            printf("%.4f\n",ans);
        }
        else if(tw%2==0&&tt==0)
        {
            if(tb0)
                printf("0.000\n");
            else
            {
                sort(ff,ff+top1,cmp1);
                for(int i=0; i<wrong; i++)
                {
                    if(fabs(ff[i].wa)<fabs(ff[i].ac))
                        ans*=fabs(ff[i].wa);
                    else
                    {
                        ans*=fabs(ff[i].ac);
                    }
                }
                for(int j=wrong; j<tot; j++)
                    ans*=fabs(ff[j].ac);
                if (fabs(ans)<eps)
                    ans=0;
                printf("%.4f\n",ans);
            }
        }
        else
        {
            int ttw=0,ttc=0;
            if(tw%2==0&&tt!=0)
            {
                wrong--;
            ttw++;
            }
            sort(cc,cc+tt,cmp2);
            sort(ff,ff+top1,cmp2);
            while(wrong)
            {
                if(wrong>=2&&tt-ttw>=2)
                {
                    if(ttc<top1)
                    {
                        if(cc[ttw].wa/cc[ttw].ac*cc[ttw+1].wa/cc[ttw+1].ac>=ff[ttc].wa/ff[ttc].ac&&cc[ttw].wa/cc[ttw].ac*cc[ttw+1].wa/cc[ttw+1].ac>1)
                        {
                            wrong-=2;
                            ttw+=2;
                        }
                        else if(cc[ttw].wa/cc[ttw].ac*cc[ttw+1].wa/cc[ttw+1].ac<ff[ttc].wa/ff[ttc].ac&&ff[ttc].wa/ff[ttc].ac>1)
                        {
                            wrong--;
                            ttc++;
                        }
                        else break;
                    }
                    else
                    {
                        if(cc[ttw].wa/cc[ttw].ac*cc[ttw+1].wa/cc[ttw+1].ac>1)
                        {
                            wrong-=2;
                            ttw+=2;
                        }
                        else break;
                    }
                }
                else if(wrong>=1)
                {
                    if(ttc<top1&&ff[ttc].wa/ff[ttc].ac>1)
                    {
                        wrong--;
                        ttc++;
                    }
                    else break;
                }
            }
            for(int i=0; i<ttw; i++)
                ans*=cc[i].wa;
            for(int i=ttw; i<tt; i++)
                ans*=cc[i].ac;
            for(int i=0; i<ttc; i++)
                ans*=ff[i].wa;
            for(int i=ttc; i<top1; i++)
                ans*=ff[i].ac;
            if (fabs(ans)<eps)
                ans=0;
            printf("%.4f\n",ans);
        }
    }
    return 0;
}