【算法实验四】--【动态规划】--花生米(五)

1086.花生米(五)

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

五一长假第六天,Tom在QQ上遇到了Kitty。呵呵,Kitty,在离散数学课上认识的PPMM……等等!Tom恍然大悟:自己这一生除了看帖不回之外最大的错误就是离散数学没学好!
五一长假第七天,Tom和Jerry在仓库散步的时候发现了一堆花生米(仓库,呵呵,仓库…)。这次Tom制定分花生米规则如下:
???????1、首先选出最苦的一粒花生米,放到一个瓶子里;
???????2、把剩下的花生米做成花生酱,Tom和Jerry轮流取一些花生酱吃掉;
???????3、第一个取的人只能取1.0克,以后取花生酱的数量不能少于两个人已经取过的总数量且不能超过两个人已经取过的总数量的三倍;
?????? 4、不能按规则3取花生酱的人必须吃掉瓶子里的花生米;
?????? 5、为显示规则的公平性,Jerry可以选择先取或者后取。
Jerry当然希望瓶子里的花生米被Tom吃掉。请计算,Jerry为了达到目的应该先取还是后取。

 

输入

本题有多个测例,每个测例的输入是一个浮点数w,w大于1.0小于等于1000.0,w最多只有一位小数,代表花生酱的数量,单位为克。
w小于0表示输入结束,不需要处理。

 

输出

每个测例在单独的一行内输出一个整数:Jerry先取输出1;Tom先取输出0。

 

输入样例

1.5
7.9
-1

 

输出样例

1
0

题解:这个嘛,就是把花生米换成了花生酱,然后每次取的数量又做了一点限制。这个结束的条件只可能是下次取完之后剩下的不足以前取过的总数量,所以导致不能完成任务。

这个跟那个花生米三有一点类似。那个是取的不能超过上次的两倍,而且第一次取一粒。对于那个题是两个参量分别是当前剩下的粒数和这次能取的最大粒数,比较条件是当前剩下的小于此次能取的最大粒数就直接可以取光获胜,若取不完,则对于每一种取得情况,有一种能输则必先取;对于本题,两个参数应为已经取过的所有粒数ate,和当前剩下的粒数cur,若ate大于剩下的,则不能满足要求必输,反之,可以取[ate,3*ate]区间的所有数量的花生酱,若有一种情况会输,则立马先取。

int dp(int ate,int cur)
{
    if(peanut[cur]>=0)
       return peanut[cur];
    if(ate>cur)
    {
       peanut[cur]=0;
       return peanut[cur];
    }
    else
    {
       int flag=1;
       for(int i=ate;i<=3*ate;i++)
       {
           peanut[cur-i]=dp(ate+i,cur-i);
           if(peanut[cur-i]==0)
           {
               flag=0;
               break;
           }
       }
       peanut[cur]=flag;
       return peanut[cur];
     }
}
    

代码如下:

#include <iostream>
#include<stdio.h>
using namespace std;
int peanut[10001];
int dp(int ate,int cur)
{
    if(peanut[cur]>=0)
       return peanut[cur];
    if(ate>cur)
    {
       peanut[cur]=0;
       return peanut[cur];
    }
    else
    {
       int flag=1;
       for(int i=ate;i<=3*ate;i++)
       {
           peanut[cur-i]=dp(ate+i,cur-i);
           if(peanut[cur-i]==0)
           {
               flag=0;
               break;
           }
       }
       peanut[cur]=1-flag;
       return peanut[cur];
    }
}
int main()
{
    double w;
    while(cin>>w&&w>=0)
    {
        for(int i=10; i<10001; i++)
			peanut[i]=-1;
        cout<<1-dp(10,int(w*10)-10)<<endl;
    }
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值