标签:
自从去年4月份学姐教完我数位DP,还是第一次写出这么漂亮的代码,也是醉了。
首先你要知道sum%(x*n) %x == sum%x,这样就可以在dfs的时候记录2到9的最小公倍数2540取余了。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define INF 0x3f3f3f3f #define Mod 6000007 //** I/O Accelerator Interface .. **/ #define g (c=getchar()) #define d isdigit(g) #define p x=x*10+c-'0' #define n x=x*10+'0'-c #define pp l/=10,p #define nn l/=10,n template<class T> inline T& RD(T &x) { char c; while(!d); x=c-'0'; while(d)p; return x; } template<class T> inline T& RDD(T &x) { char c; while(g,c!='-'&&!isdigit(c)); if (c=='-') { x='0'-g; while(d)n; } else { x=c-'0'; while(d)p; } return x; } inline double& RF(double &x) //scanf("%lf", &x); { char c; while(g,c!='-'&&c!='.'&&!isdigit(c)); if(c=='-')if(g=='.') { x=0; double l=1; while(d)nn; x*=l; } else { x='0'-c; while(d)n; if(c=='.') { double l=1; while(d)nn; x*=l; } } else if(c=='.') { x=0; double l=1; while(d)pp; x*=l; } else { x=c-'0'; while(d)p; if(c=='.') { double l=1; while(d)pp; x*=l; } } return x; } #undef nn #undef pp #undef n #undef p #undef d #undef g using namespace std; LL dp[22][257][2521]; int num[21]; LL dfs(int up,int site,int sta,int mod,int bot) { if(site > bot) { for(int i = 2;i <= 9; ++i) if((sta&(1<<(i-2))) && mod%i != 0) return dp[site][sta][mod] = 0; return dp[site][sta][mod] = 1; } if(up == 0 && dp[site][sta][mod] != -1) return dp[site][sta][mod]; int i; LL ans = 0; if(up == 0) { ans += dfs(0,site+1,sta,(mod*10+0)%2520,bot); ans += dfs(0,site+1,sta,(mod*10+1)%2520,bot); for(i = 2;i <= 9; ++i) ans += dfs(0,site+1,sta|(1<<(i-2)),(mod*10+i)%2520,bot); return dp[site][sta][mod] = ans; } else { if(0 <= num[site]) ans += dfs(0 == num[site] ? 1 : 0,site+1,sta,(mod*10+0)%2520,bot); if(1 <= num[site]) ans += dfs(1 == num[site] ? 1 : 0,site+1,sta,(mod*10+1)%2520,bot); for(i = 2;i <= num[site]; ++i) ans += dfs(i == num[site] ? 1 : 0,site+1,sta|(1<<(i-2)),(mod*10+i)%2520,bot); return ans; } } LL Cal(LL x) { if(x == 0) return 1; int i; for(i = 20;x; --i) num[i] = x%10,x /= 10; return dfs(1,i+1,0,0,20); } int main() { int T,icase; int n,i,j; scanf("%d",&T); memset(dp,-1,sizeof(dp)); for(icase = 1;icase <= T; icase++) { LL l,r; cin>>l>>r; cout<<Cal(r)-Cal(l-1)<<endl; } return 0; }
Codeforces 55D Beautiful numbers 数位DP
标签:
原文地址:http://blog.csdn.net/zmx354/article/details/42880403