BZOJ1026 [SCOI2009]windy数(数位dp)
2015-01-31 19:27
441 查看
Ac了“GT考试”以后,感觉这题还是蛮基础的
【题解】
先预处理出数组dp、f:
dp[i][j]表示:第i位填j的windy数有多少个(个位为第1位,十位为第2位……)
状态转移:每次在最左边填一个数:
dp[i][j]=sigma(dp[i-1][k]),0<=k<=9且abs(j-k)>=2
边界:dp[1][j]=1
从A至B计数时,若A与B位数不等,则最高位可以是0,用f[i]记录以第i位为最高位,最高位是0的windy数个数
那么,f[i]=f[i-1]+sigma(dp[i-1][j]),1<=j<=9
计数:
1.既有下届又有上界很麻烦,可以运用前缀和的思想
2.从高位到低位填数
统计0~x中windy数个数:设x第i位的数为num[i],当上一位填num[i+1]时(最高位特殊处理):
首先,这一位可以为0~num[i]-1,后面随便填,ans+=sigma(dp[i-1][j]),若i不是最高位,要注意与上一位的差>=2
然后,这一位可以为num[i],ans与下一位有关,处理下一位
【题解】
先预处理出数组dp、f:
dp[i][j]表示:第i位填j的windy数有多少个(个位为第1位,十位为第2位……)
状态转移:每次在最左边填一个数:
dp[i][j]=sigma(dp[i-1][k]),0<=k<=9且abs(j-k)>=2
边界:dp[1][j]=1
从A至B计数时,若A与B位数不等,则最高位可以是0,用f[i]记录以第i位为最高位,最高位是0的windy数个数
那么,f[i]=f[i-1]+sigma(dp[i-1][j]),1<=j<=9
计数:
1.既有下届又有上界很麻烦,可以运用前缀和的思想
2.从高位到低位填数
统计0~x中windy数个数:设x第i位的数为num[i],当上一位填num[i+1]时(最高位特殊处理):
首先,这一位可以为0~num[i]-1,后面随便填,ans+=sigma(dp[i-1][j]),若i不是最高位,要注意与上一位的差>=2
然后,这一位可以为num[i],ans与下一位有关,处理下一位
#include<stdio.h> #include<stdlib.h> #include<math.h> typedef long long LL; LL dp[20][20]={0},f[20]={0}; void init() { int i,j,k; f[1]=1; for(i=0;i<=9;i++) dp[1][i]=1; for(i=2;i<=10;i++) { for(j=0;j<=9;j++) for(k=0;k<=9;k++) if(abs(j-k)>=2) dp[i][j]+=dp[i-1][k]; f[i]=f[i-1]; for(j=1;j<=9;j++) f[i]+=dp[i-1][j]; } } LL solve(int x)//求出0~x-1中windy数的个数 { int num[20]={0}; LL ans=0; int p=0,i,j; while(x!=0) { num[++p]=x%10; x/=10; } ans=f[p];//最高位填0 for(i=1;i<num[p];i++)//最高位填1~num[p]-1 ans+=dp[p][i]; for(i=p-1;i>=1;i--)//最高位填num[p],向后考虑 { for(j=0;j<num[i];j++) if(abs(num[i+1]-j)>=2) ans+=dp[i][j]; if(abs(num[i+1]-num[i])<2) break; } return ans; } int main() { int A,B; scanf("%d%d",&A,&B); init(); printf("%lld",solve(B+1)-solve(A));//注意 return 0; }
相关文章推荐
- [BZOJ1026][SCOI2009]windy数 解题报告|数位dp
- bzoj 1026 [SCOI2009]windy数 数位dp
- 【BZOJ】1026: [SCOI2009]windy数(数位dp)
- bzoj1026 [SCOI2009]windy数(数位dp)
- BZOJ 1026: [SCOI2009]windy数 (裸的数位dp)
- 【BZOJ1026】【SCOI2009】windy数 数位DP
- bzoj1026[SCOI2009]windy数 【数位dp】
- BZOJ.1026.[SCOI2009]windy数(数位DP)
- 【BZOJ 1026】【SCOI 2009】windy数 【数位DP】
- bzoj 1026: [SCOI2009]windy数 数位dp
- BZOJ 1026 [SCOI2009]windy数【数位DP】
- 【BZOJ】1026 [SCOI2009]windy数 数位dp
- [数位dp] bzoj1026: [SCOI2009]windy数
- _bzoj1026 [SCOI2009]windy数【数位dp】
- [SCOI 2009]BZOJ 1026 windy数 - 数位dp
- [bzoj1026][SCOI2009]windy数_数位dp
- BZOJ_1026_[SCOI2009]_windy数_(数位dp)
- bzoj 1026: [SCOI2009]windy数(数位dp)
- [BZOJ1026][SCOI2009]windy数 && 数位DP
- bzoj 1026: [SCOI2009]windy数【数位dp】