[置顶] 大水题

【问题描述】
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\n",ans);
}
int main()
{
    freopen("water.in","r",stdin);
    freopen("water.out","w",stdout);
    init();
    work();
    fclose(stdin);
    fclose(stdout);
    return 0;
}
posted @ 2017-08-17 17:51  小蒟蒻ysn  阅读(354)  评论(0编辑  收藏  举报