hdu5787K-wolf Number
2016-08-02 17:27
30 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787
题意:求l~r范围内有多少个数满足连续的k位数中不存在重复的数字。
分析:数位dp,仔细处理好细节即可。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=2000010; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int INF=1000000010; const ll MAX=1ll<<55; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; int d[20],s[9]; bool q[2][20][10000][6]; bool f[2][10000][10][6]; ll dp[2][20][10000][6]; int pd(int rev,int pre,int i,int k) { if (rev) { for (int h=1;h<k;h++) if ((pre/s[h])%10==i) return 0; } else { for (int h=1;h<k&&s[h]<=pre;h++) if ((pre/s[h])%10==i) return 0; } return 1; } ll cala(int rev,int x,int pre,int k,int bo) { if (x==0) return 1; if (bo&&q[rev][x][pre][k]) return dp[rev][x][pre][k]; if (bo) { ll& ret=dp[rev][x][pre][k]; q[rev][x][pre][k]=1; for (int i=0;i<10;i++) if (f[rev][pre][i][k]) { if (rev) ret+=cala(rev,x-1,(pre*10+i)%s[k],k,bo); else ret+=cala(pre/s[k-1]!=0?1:0,x-1,(pre*10+i)%s[k],k,bo); } return ret; } else { ll ret=0; for (int i=0;i<d[x];i++) if (f[rev][pre][i][k]) { if (rev) ret+=cala(rev,x-1,(pre*10+i)%s[k],k,1); else ret+=cala(pre/s[k-1]!=0?1:0,x-1,(pre*10+i)%s[k],k,1); } if (f[rev][pre][d[x]][k]) { if (rev) ret+=cala(rev,x-1,(pre*10+d[x])%s[k],k,0); else ret+=cala(pre/s[k-1]!=0?1:0,x-1,(pre*10+d[x])%s[k],k,0); } return ret; } } ll get(ll x,int k) { int len=0; while (x) { d[++len]=x%10;x/=10; } return cala(0,len,0,k,0); } void deal() { int i,j,k,h; memset(q,0,sizeof(q)); memset(f,0,sizeof(f)); for (s[1]=1,i=2;i<9;i++) s[i]=s[i-1]*10; for (i=0;i<10;i++) for (j=2;j<6;j++) for (k=0;k<100000;k++) if (k>=s[j]) break ; else { f[0][k][i][j]=1; for (h=1;h<j&&s[h]<=k;h++) if ((k/s[h])%10==i) f[0][k][i][j]=0; } for (i=0;i<10;i++) for (j=2;j<6;j++) for (k=0;k<100000;k++) if (k>=s[j]) break ; else { f[1][k][i][j]=1; for (h=1;h<j;h++) if ((k/s[h])%10==i) f[1][k][i][j]=0; } } int main() { int i,k; ll l,r;deal(); memset(q,0,sizeof(q)); while (scanf("%I64d%I64d%d", &l, &r, &k)!=EOF) { printf("%I64d\n", get(r,k)-get(l-1,k)); } return 0; }
相关文章推荐
- hdu5787K-wolf Number(数位dp)
- hdu 5787 K-wolf Number (数位DP )
- HDU 5787 K-wolf Number(数位DP)
- hdoj 5787 K-wolf Number 数位dp xjb搞水过
- HDU 5787 K-wolf Number
- HDOJ 5787 K-wolf Number 数位DP
- HDU 5787 K-wolf Number
- hdu5787 K-wolf Number【数位dp】
- hdu-5787-K-wolf Number-数位DP
- [HDOJ5787]K-wolf Number(数位DP)
- HDU 5787 K-wolf Number 数位dp
- HDU 5787 K-wolf Number
- HDU5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number
- HDU 5787 K-wolf Number(数位DP)
- hdu 5787 K-wolf Number 数位dp
- HDU 5787 K-wolf Number
- [暑假集训--数位dp]hdu5787 K-wolf Number
- HDU 5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number 数位DP