HDU 4722-Good Numbers-数位dp
2016-04-19 00:18
543 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4722
题目求A到B之间有多少个lucky number,它的定义是各位数加起来 能被10整除
我的做法是直接 for i,j,k 求出 dp[i][j]表示 前i位数中,各位和模10为j的方案数
也就是当i=5,dp[i][j]表示 1到 99999 的所有数 中 各位和模10为j的个数
那么实际我们要求的是【1,A】的个数,例如A=76543,这时我们拿1到99999的方案数dp[i][0] ,减去 dp[4][2] (因为所有第i位数以8开头的数中,只要后面四位的和取模为2,则加起来就可以整除10,所以去掉这部分),然后再减去dp[4][1](这部分是去掉9开头的部分),以此类推,得到了79999的方案,再得到76999的方案,再得到76599最后得到 【1,76543】的方案
【当然你可以直接从低位往高位推比较简单】
最后答案是 【1,B】-【1,A】,特判A是否为答案即可
题目求A到B之间有多少个lucky number,它的定义是各位数加起来 能被10整除
我的做法是直接 for i,j,k 求出 dp[i][j]表示 前i位数中,各位和模10为j的方案数
也就是当i=5,dp[i][j]表示 1到 99999 的所有数 中 各位和模10为j的个数
那么实际我们要求的是【1,A】的个数,例如A=76543,这时我们拿1到99999的方案数dp[i][0] ,减去 dp[4][2] (因为所有第i位数以8开头的数中,只要后面四位的和取模为2,则加起来就可以整除10,所以去掉这部分),然后再减去dp[4][1](这部分是去掉9开头的部分),以此类推,得到了79999的方案,再得到76999的方案,再得到76599最后得到 【1,76543】的方案
【当然你可以直接从低位往高位推比较简单】
最后答案是 【1,B】-【1,A】,特判A是否为答案即可
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<set> #include<map> #include<vector> using namespace std; #define INF 0x3f3f3f3f3f3f3f #define MAX 100005 __int64 dp[20][15]; int judge(__int64 x) { __int64 sum=0; while(x) { sum+=x%10; x/=10; } if (sum%10==0)return 1; return 0; } int aa[20]; int sum[20]; int main() { //freopen("xl_in.txt","r",stdin); int i,j,k; dp[0][0]=1; for (i=0;i<=18;i++) { for (j=0;j<=9;j++) { for (k=0;k<=9;k++) { dp[i+1][(k+j)%10]+=dp[i][j]; } } } /*for (i=0;i<=1000;i++) { printf("%d ",); }*/ int t,cas=0; cin>>t; while(t--) { __int64 a,b; cin>>a>>b; __int64 tmp=a; int ok=0; while(tmp) { aa[++ok]=tmp%10; tmp/=10; } sum[ok+1]=0; for (i=ok;i>=1;i--) sum[i]=sum[i+1]+aa[i]; __int64 sum1=dp[ok][0]; for (i=ok;i>=1;i--) { for (j=9;j>aa[i];j--) { sum1-=dp[i-1][(10-((j+sum[i+1])%10))%10]; } } // printf("%d\n",sum1); tmp=b; ok=0; while(tmp) { aa[++ok]=tmp%10; tmp/=10; } sum[ok+1]=0; for (i=ok;i>=1;i--) sum[i]=sum[i+1]+aa[i]; __int64 sum2=dp[ok][0]; for (i=ok;i>=1;i--) { for (j=9;j>aa[i];j--) { sum2-=dp[i-1][(10-((j+sum[i+1])%10))%10]; } } //printf("%I64d\n",sum2); __int64 ans=sum2-sum1; if (judge(a)) ans++; cas++; printf("Case #%d: %I64d\n",cas,ans); } return 0; }
相关文章推荐
- django类视图浅析
- 源码编译安装GO1.6
- [django]入门教程2:视图开发-定义视图函数及配置相应URL
- poj-2262-Goldbach's Conjecture
- golang Md5+salt
- 初见Go
- BitGo CEO谈扩容:谁能最终决…
- BitGo公司推出比特币交易工具“Inst…
- GOF设计模式笔记之创建型模式
- [django]入门教程1:安装配置并创建项目
- Coinbase和BitGo扩张全球比特币和…
- 用polygon模型去切CV曲线的工具
- django学习的一些碎片化知识
- DrawerLayout 模仿google官方左滑,menu内容延伸到通知栏
- 二叉搜索树实现 in Go语言
- HDU 1824 Let's go home 2-Sat
- golang交叉编译
- Good Tools for downloading Youtube source
- 2016 Google Code Jam Round 1A (A. The Last Word,B. Rank and File,C. BFFs(二元环))
- django 更改默认语言和时间