[数位dp] Jzoj P3363 Number
题解
- 暴力预处理出那些是不合法的情况
- 在后面dp中,遇到可以被连读也就是预处理出来的情况直接赋0
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 struct edge {int l,v;}a[110]; 7 int n,mi[20],g[12][100000],f[100000][101],p[10][2]={{0,0},{5,5},{4,4},{3,3},{8,3},{8,4},{7,4},{7,3},{11,3},{11,4}}; 8 char s[20]; 9 long long ans; 10 int main() 11 { 12 mi[0]=1; for (int i=1;i<=9;i++) mi[i]=mi[i-1]*10; 13 scanf("%d",&n); 14 for (int i=1;i<=n;i++) 15 { 16 scanf("%s",s+1); 17 a[i].l=strlen(s+1); 18 for (int j=a[i].l;j>=1;j--) a[i].v=a[i].v*10+s[j]-'0'; 19 } 20 for (int i=1;i<=n;i++) 21 for (int j=0;j<=99999;j++) 22 for (int k=1;k<=6-a[i].l;k++) 23 if ((j%mi[a[i].l+k-1])/mi[k-1]==a[i].v) 24 { 25 f[j][++f[j][0]]=a[i].l+k-1; 26 break; 27 } 28 g[0][0]=1; 29 for (int i=1;i<=11;i++) 30 { 31 for (int j=0;j<=99999;j++) 32 for (int k=0;k<=9;k++) 33 g[i][j%mi[4]*10+k]+=g[i-1][j]; 34 for (int j=1;j<=9;j++) 35 if (p[j][0]==i) 36 for (int k=0;k<=99999;k++) 37 if (g[i][k]) 38 for (int z=1;z<=f[k][0];z++) 39 if (f[k][z]<=p[j][1]) 40 { 41 g[i][k]=0; 42 break; 43 } 44 } 45 for (int i=0;i<=99999;i++) if (i%10==1) ans+=g[11][i]; 46 printf("%lld",ans); 47 }