zoukankan      html  css  js  c++  java
  • [置顶] 大水题

    【问题描述】
    dzy 定义一个n^2 位的数的生成矩阵A 为一个大小为n*n 且Aij 为这个数的第i*n+j-n位的矩阵。
    现在dzy 有一个数n^2 位的数k,他想知道所有小于等于k 的数的n*n 生成矩阵有多少种。(如果不足n^2 位则补前缀零)

    【输入】

    第一行一个数n,第二行一个n^2 位的数k

    【输出】
    仅一行表示答案,答案可能很大,你只需输出答案对10^9 + 7 取模后的结果。

    【输入输出样例】

    water.in
    2
    1000
    water.out
    954

    【数据规模和约定】
    对于30% 的数据n<=2
    对于100% 的数据n <=1000,且n为偶数

    【提示】
    如果两个生成矩阵在其中一个旋转180 度后可以重叠,则称这两个矩阵是相同的。

    【题解】
    数位DP

    算法1:
    直接暴力到底,复杂度是这里写图片描述,期望得分30分。

    算法2:
    令 f(i,n) 表示把i在 n2位十进制下反转得到的数,则有:
    这里写图片描述
    分子中的两项都可以用数位DP求出,首先考虑第一项:
    令表示DP的状态,表示 k 前 i 位组成的数,表示 k 后 i 位组成的数,表示k 前 i 位倒序组成的数,则定义:
    这里写图片描述
    显然这是可以递推的。
    接下来考虑第二项:
    这里写图片描述
    求出这两项后代入上式即可得到答案,时间复杂度 O(n2 ),期望得分100 分。

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define fp(i,a,b) for(int i=a;i<=b;i++)
    #define fq(i,a,b) for(int i=a;i>=b;i--)
    #define il inline
    #define ll long long 
    using namespace std;
    const int mod=1e9+7;
    const int M=500000004;
    const int maxn=1010*1010;
    ll n,m,ans,cnt,a[maxn],f[maxn][2][2];
    char s[maxn];
    il int gi()
    {
       int x=0;
       short int t=1;
       char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il void init()
    {
        n=gi();
        n*=n;
        scanf("%s",s+1);
        fp(i,1,n)
            a[i]=s[i]-'0',ans=(ans*10+a[i])%mod;
    }
    il void work()
    {
        f[0][0][1]=1;
        fp(i,0,n-1)
          fp(j,0,1)
            fp(k,0,1)
            {
                if(!f[i][j][k]) continue;
                fp(l,0,9)
                {
                    if(j||a[i+1]>=l)
                    {
                       bool b=(a[i+1]>l||j)?1:0;
                       bool c=(a[n-i]>l||l==a[n-i]&&k)?1:0;
                        (f[i+1][b][c]+=f[i][j][k])%=mod;
                    }
                }
           }
        cnt=(f[n][0][1]+f[n][1][1])%mod;
        cnt=(cnt-f[n/2][1][1]-f[n/2][1][0]-f[n/2][0][1])%mod;
        cnt=cnt*M%mod;
        ans=((ans-cnt)%mod+mod)%mod;
        printf("%lld
    ",ans);
    }
    int main()
    {
        freopen("water.in","r",stdin);
        freopen("water.out","w",stdout);
        init();
        work();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    day4
    cache用法
    Excel批量生成SQL语句,处理大量数据(增,改)
    IDEA中Maven依赖下载失败解决方案
    IDEA 自动生成类图 UML
    springboot报错说 Failed to parse multipart servlet request; nested exception is java.io.IOException
    controller层的引用service层一直报空指针问题
    CONCATENATE函数
    AQS
    String 类和常量池
  • 原文地址:https://www.cnblogs.com/yanshannan/p/7392295.html
Copyright © 2011-2022 走看看