hdu 4722 Good Numbers
2013-09-13 21:54
211 查看
题意:给你一个区间,让你求满足条件的数的个数,满足的条件:该数每位相加能被10整除。
分析:一个典型的数位DP,只要想出状态方程就会变得很简单,这时候就可以想到状态相关的条件,里面最重要的是能被10整除,通常的数位DP都是二维,这里就需要多加一维来记录余数情况就能知道能否被10整除了,因此状态方程可以得出:dp[ i ][ j ][ ( k + j ) % 10]=sum{ 0<=t<=9 | dp[ i - 1 ][ t ][ k ] }
附代码:
分析:一个典型的数位DP,只要想出状态方程就会变得很简单,这时候就可以想到状态相关的条件,里面最重要的是能被10整除,通常的数位DP都是二维,这里就需要多加一维来记录余数情况就能知道能否被10整除了,因此状态方程可以得出:dp[ i ][ j ][ ( k + j ) % 10]=sum{ 0<=t<=9 | dp[ i - 1 ][ t ][ k ] }
附代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long ll; const int maxn = 21; ll dp[maxn][11][11]; void init(){ memset(dp,0,sizeof(dp)); for(int i=0;i<=9;i++){ dp[1][i][i]=1; } for(int i=2;i<20;i++){ for(int j=0;j<=9;j++){ for(int t=0;t<=9;t++){ for(int k=0;k<=9;k++){ dp[i][j][(k+j)%10]+=dp[i-1][t][k]; } } } } } ll w[maxn]; int dige(ll n){ int ret=0; while(n){ w[ret]=n%10; n/=10; ret++; } return ret; } ll num(ll n){ int Maxdig=dige(n); ll sum1=0; int flag=0; for(int i=Maxdig;i>=1;i--){ if(i!=1){ for(int j=0;j<w[i-1];j++){ sum1+=dp[i][j][(10-flag)%10]; } } else{ for(int j=0;j<=w[i-1];j++){ sum1+=dp[i][j][(10-flag)%10]; } } flag+=w[i-1]; flag%=10; } return sum1; } int main(){ int T; scanf("%d",&T); init(); int con=1; while(T--){ ll n,m; scanf("%I64d %I64d",&n,&m); printf("Case #%d: %I64d\n",con++,num(m)-num(n-1)); } }
相关文章推荐
- hdu 4722 Good Numbers(数位dp)
- HDU-4722-Good Numbers(找规律)
- Hdu 4722 Good Numbers
- HDU 4722 Good Numbers
- HDU 4722 Good Numbers 2013年四川省赛题
- [数位dp] hdu 4722 Good Numbers
- hdu 4722 Good Numbers
- HDU 4722 Good Numbers 数位dp或找规律枚举 数位dp感悟
- HDU 4722 Good Numbers(数位DP)
- HDU 4722 Good Numbers(找规律)
- HDU 4722 Good Numbers
- hdu 4722 Good Numbers
- HDU 4722 Good Numbers
- hdu 4722 Good Numbers 2013 ACM/ICPC Asia Regional Online —— Warmup2
- HDU4722——Good Numbers——2013 ACM/ICPC Asia Regional Online —— Warmup2
- HDU 4722 Good Numbers
- HDU 4722 Good Numbers
- HDU-4722 Good Numbers 数位DP
- hdu 4722 Good Numbers
- hdu 4722 Good Numbers 数位DP