一开始题看错了。。。dp[pos][sets][viss],其中sets表示出现次数,viss表示出现没有。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long t,l,r,dp[22][1025][1025],bit[22],ret=0; void get_bit(long long x) { ret=0; while (x) {bit[++ret]=x%10;x/=10;} } long long check(long long sets,long long viss) { for (long long i=0;i<=9;i++) { if (!(viss&(1<<i))) continue; if ((i&1) && (sets&(1<<i))) return 0; if ((!(i&1)) && (!(sets&(1<<i)))) return 0; } return 1; } long long dfs(long long pos,long long sets,long long viss,bool flag) { if (!pos) return check(sets,viss); if ((!flag) && (~dp[pos][sets][viss])) return dp[pos][sets][viss]; long long ans=0,up=flag?bit[pos]:9; for (long long i=0;i<=up;i++) ans+=dfs(pos-1,sets^(1<<i),viss|(1<<i),flag&&(i==up)); if (!flag) dp[pos][sets][viss]=ans; return ans; } long long work(long long x) { if (!x) return 0; get_bit(x);long long ans=0; for (long long i=1;i<=ret-1;i++) for (long long j=1;j<=9;j++) ans+=dfs(i-1,1<<j,1<<j,0); for (long long j=1;j<=bit[ret]-1;j++) ans+=dfs(ret-1,1<<j,1<<j,0); ans+=dfs(ret-1,1<<bit[ret],1<<bit[ret],1); return ans; } int main() { scanf("%lld",&t);memset(dp,-1,sizeof(dp)); for (long long i=1;i<=t;i++) { scanf("%lld%lld",&l,&r); printf("%lld ",work(r)-work(l-1)); } return 0; }