Codeforce Gym 100819L : 2015-2016 ACM-ICPC Pacific Northwest Regional Contest - L 这是一道阅读理解(微笑)

题目(VJ) Gym - 100819L Codeforces-Gym Dashboard - 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) PDF 20152016-acmicpc-pacific-northwest-regional-contest-div-2-en.pdfgit

讲道理第一题都应该是水题的。。。然而这是一道阅读理解... 读了三个多小时也没弄明白Sample2的那个数怎么算出来的,后来实在无聊从后往前算发现happiness正好算出来了...日啊... 官方的解释是这样的:github

 One should start by converting all the dollar values to happiness units and working with those; converting the final answer back to dollars is straightforward algebra.

To play Millionaire optimally, you want to determine how far you can go before you should take your winnings so far and quit, refusing to answer any further questions. The key observation is, once you've made it to a particular question, there's no additional history you need to worry about. So you can solve it backwards: assuming you make it to the final question, should you try to answer it or quit? If you quit, you receive the penultimate prize. If you try, the possible outcomes are success and failure, and your expected happiness is a weighted average of the two. Having determined whether to try or quit at the final question, now work backwards to the penultimate question and so on all the way back to the first question.

While a recursive solution risks overflowing the program stack, the same idea can be implemented by scanning over the questions backwards.

沃日...真是阅读理解啊...app

AC代码 View Source On GitHubide

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

#include <algorithm>
using namespace std;
#define MAXROUND 100005
double safemoney[MAXROUND];
double roundmoney[MAXROUND];
double p[MAXROUND];
char str[256];
inline double ln(double inc)
{
    return log(inc);
}
int main()
{
    int n,W;
    scanf("%d %d",&n,&W);
    for(int i=0;i<n;i++)
    {
        scanf("%s %lf %lf",str,&p[i],&roundmoney[i+1]);
        roundmoney[i+1]=ln(1+roundmoney[i+1]/W);
        if(strcmp(str,"safe")==0)
        {
            safemoney[i+1]=roundmoney[i+1];
        }
        else
        {
            safemoney[i+1]=safemoney[i];
        }
    }
    for(int i=n-1;i>=0;i--)
    {
        double tmp=p[i]*roundmoney[i+1]+(1-p[i])*safemoney[i];
        roundmoney[i]=max(tmp,roundmoney[i]);
    }
    double ans=(exp(roundmoney[0])-1)*W;
    printf("$%.2f\n",ans);
}