• 洛谷 P4882 lty loves 96! 解题报告


    P4882 lty loves 96!

    题目背景

    众所周知,(lty)非常喜欢(96)这两个数字(想歪的现在马上面壁去),更甚于复读(人本复)!

    题目描述

    由于爱屋及乌,因此,(lty)对于那些含有(96)的数也非常喜欢,而这里的含有不是一般的含有,而是具有以下性质的含有(三条都需要满足):

    这个数为一个(N)位数,且没有前置零
    这个数中至少要出现(M)(9)(6)(例:(986996)中出现了(5)次,(9)出现了(3)次,(6)出现了(2)次,共计(5)次)
    这个数存在任意连续的从高到低三位(A,B,C),满足下面任意一条
    (A+B+C)(9)(6)
    ((A^2+B^2)\%C)(9)(6),如果(C)(0),则该条件视为不满足

    输入输出格式

    输入格式:

    一行,两个数(N),(M)

    输出格式:

    一个数,表示这样的数的个数

    说明

    对于10%的数据,(N<=6)
    对于40%的数据,(N<=18)
    对于100%的数据,(N<=50,0<=M<=N)


    人生第一道数位DP

    (dp_{i,j,k,l,q})从高到低前(i)位第(i)位为(j),第(i-1)位为(k),一共有(l)(6)(9),是否已经满足条件的方案数

    注意前导0,注意要压位高精。


    Code:

    #include <cstdio>
    #include <cstring>
    int max(int x,int y){return x>y?x:y;}
    struct node
    {
        int num[20];
        node()
        {
            memset(num,0,sizeof(num));
            num[0]=1;
        }
        node(int i)
        {
            memset(num,0,sizeof(num));
            num[0]=1,num[1]=i;
        }
        node friend operator +(node n1,node n2)
        {
            int len=max(n1.num[0],n2.num[0]);
            node n3;
            n3.num[0]=len;
            for(int i=1;i<=len;i++)
            {
                n3.num[i]+=n1.num[i]+n2.num[i];
                n3.num[i+1]=n3.num[i]/10000;
                n3.num[i]%=10000;
            }
            if(n3.num[len+1]) ++n3.num[0];
            return n3;
        }
    }dp[51][10][10][51][2];
    int n,m;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<=9;i++)
            for(int j=1;j<=9;j++)
            {
                if((i==6||i==9)&&(j==6||j==9))
                    dp[2][i][j][2][0]=node(1);
                else if(i==6||i==9)
                    dp[2][i][j][1][0]=node(1);
                else if(j==6||j==9)
                    dp[2][i][j][1][0]=node(1);
                else
                    dp[2][i][j][0][0]=node(1);
            }
        for(int i=3;i<=n;i++)
            for(int l3=0;l3<=9;l3++)
                for(int l2=0;l2<=9;l2++)
                    for(int l1=0;l1<=9;l1++)
                    {
                        int s1=l1+l2+l3,s2=l1?(l3*l3+l2*l2)%l1:0;
                        for(int j=0;j<=i;j++)
                        {
                            if(s1==6||s1==9||s2==6||s2==9)
                            {
                                if(l1==6||l1==9)
                                {
                                    if(!j) continue;
                                    dp[i][l1][l2][j][1]=dp[i][l1][l2][j][1]
                                                       +dp[i-1][l2][l3][j-1][1]
                                                       +dp[i-1][l2][l3][j-1][0];
                                }
                                else
                                {
                                    dp[i][l1][l2][j][1]=dp[i][l1][l2][j][1]
                                                       +dp[i-1][l2][l3][j][1]
                                                       +dp[i-1][l2][l3][j][0];
                                }
                            }
                            else
                            {
                                if(l1==6||l1==9)
                                {
                                    if(!j) continue;
                                    dp[i][l1][l2][j][0]=dp[i][l1][l2][j][0]
                                                       +dp[i-1][l2][l3][j-1][0];
                                    dp[i][l1][l2][j][1]=dp[i][l1][l2][j][1]
                                                       +dp[i-1][l2][l3][j-1][1];
                                }
                                else
                                {
                                    dp[i][l1][l2][j][0]=dp[i][l1][l2][j][0]
                                                       +dp[i-1][l2][l3][j][0];
                                    dp[i][l1][l2][j][1]=dp[i][l1][l2][j][1]
                                                       +dp[i-1][l2][l3][j][1];
                                }
                            }
    
                        }
                    }
        node ans=node(0);
        for(int i=0;i<=9;i++)
            for(int j=0;j<=9;j++)
                for(int l=m;l<=n;l++)
                    ans=ans+dp[n][i][j][l][1];
        printf("%d",ans.num[ans.num[0]]);
        for(int i=ans.num[0]-1;i;i--)
        {
            if(ans.num[i]<1000) printf("0");
            if(ans.num[i]<100) printf("0");
            if(ans.num[i]<10) printf("0");
            printf("%d",ans.num[i]);
        }
        return 0;
    }
    

    2018.9.9

  • 相关阅读:
    leetcode ---Search a 2D Matrix
    leetcode ---Search for a Range
    LeetCode--Search in Rotated Sorted Array
    LeetCode--setatrixzeroes
    LeetCode--sortColor
    LeetCode--Spiral Matrix
    java io类 和servlet类 的UML图表示
    servlet web.xml配置详解
    解决json日期格式带T问题
    在拦截器中获取请求参数,[Ljava.lang.String; cannot be cast to java.lang.String报错
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9614578.html
Copyright © 2020-2023  润新知