[DP]石头剪刀布

题目描述

小明和小头遇到了矛盾,他们决定用男人的方式解决战斗——石头剪刀布。但是小菜觉得石头剪刀布已经过时了,于是他发明了另一个更男人的游戏。小菜给出一个自然数n,小明和小头轮流操作,每次操作可以把n减去n所拥有的数字中的最大值或者最小值(不包括0),不能操作者输(即当n=0时)。
  小菜怕他们不懂,于是给了一个例子n=1024,则最大值=4,最小值=1。假如小明先操作,那么他可以留给小头1023或者1020。
  小明和小头觉得这个游戏很好玩,于是打算多玩几局。每次由小明先操作,如果两人都是用最佳策略,请问谁会赢?

Input

  第一行只有一个整数t,表示玩t轮游戏
  接下来t行,每行一个自然数n,表示初始时小菜给出的自然数。

Output

  共t行,如果小明赢了第i轮游戏则在第i行输出“YES” 否则输出“NO”

Sample Input

2
9
10

Sample Output

YES
NO

Data Constraint

【数据规模】
  40%的数据n≤50
  100%的数据t≤100,n≤1000000
  

分析

显然我们发现这个输赢是奇偶分配的,所以可以转移动态
fi=!fj
那么j是什么呢?
就是i-i中最大值和i-i中最小值,那么设这两为j,k得
fi=!fj∨!fk
那么我们预处理1~10^6的所有值即可

#include <iostream>
#include <cstdio>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
int t,n,i,j;
bool f[1000001];
int main()
{
    scanf("%d",&t);
    f[0]=0;
    rep(i,1,1000000)
    {

        int mxn=0,mnn=2147483647,x=i;
        while (x>0)
        {
            if (x%10!=0)
            {
                mxn=max(mxn,x%10);
                mnn=min(mnn,x%10);
            }
            x/=10;
        }
        f[i]=!f[i-mxn]||!f[i-mnn];
    }
    rep(i,1,t)
    {
        scanf("%d",&n);
        if (f[n])
        printf("YES\n");
        else printf("NO\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值