HDU 3709 Balanced Number (数位DP)
2015-10-04 22:37
246 查看
题意:
找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数。
思路:
一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会MLE。
其实只需要3维 [第几位][和][轴位置],对于轴的位置是需要枚举的,每个位都是有可能的,比如900和7都是一个平衡数。注意这道题的区间下限可能为0,而0也是平衡数,这在拆十进制的时候len=0的,最好将0特处理。
AC代码
找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数。
思路:
一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会MLE。
其实只需要3维 [第几位][和][轴位置],对于轴的位置是需要枚举的,每个位都是有可能的,比如900和7都是一个平衡数。注意这道题的区间下限可能为0,而0也是平衡数,这在拆十进制的时候len=0的,最好将0特处理。
#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <algorithm> #include <vector> #include <iostream> #define pii pair<int,int> #define INF 0x7f3f3f3f #define LL long long #define ULL unsigned long long using namespace std; const double PI = acos(-1.0); const int N=19; LL f [325] , bit ; //[第几位][和][轴] LL dfs(int i,int sum,int mid,bool e) { if(i==0) return sum==0; if(sum<0 || sum>=325) return 0; if(!e && ~f[i][sum][mid]) return f[i][sum][mid]; LL ans=0; int u= e? bit[i]: 9; for(int d=0; d<=u; d++) { if(sum==0 && i==mid && d==0) continue; //首位是mid,必须不为0 ans+=dfs(i-1, sum+(i-mid)*d, mid, e&&d==u); //注意不能为负 } return e? ans: f[i][sum][mid]=ans; } LL cal(LL n) { if(n<0) return 0; int len=0; while(n) //拆数 { bit[++len]=n%10; n/=10; } LL ans=1; //dfs是没有统计0的,因为len=0是不会执行dfs的 for(int i=1; i<=len; i++) ans+=dfs(len, 0, i, true); return ans; } int main() { //freopen("input.txt","r",stdin); memset(f,-1,sizeof(f)); LL L,R;int t;cin>>t; while( t-- ) { cin>>L>>R; cout<<cal(R)-cal(L-1)<<endl; } return 0; }
AC代码
相关文章推荐
- 【小游戏】俄罗斯方块(C++版)
- 【小游戏】俄罗斯方块(C++版)
- HTML冷门标签
- 富人跟穷人的区别
- Android动画学习总结---中
- pomelo使用中的常见问题
- USACO 2.3.4 Money Systems
- CSS样式----CSS属性:字体属性和文本属性(图文详解)
- 学习linux/unix编程方法的建议
- 安装Adobe系列产品出现致命错误:FATAL: Payload
- 第4周SHH数据结构—【项目2-实现单链表算法库】
- C语言的链接属性的个人理解
- 【NOIP模拟】20151004模拟
- C++primer学习:string类的练习(2)
- hdu 5495 LCS dfs
- CF 582A(GCD Table-贪心)
- POJ 1195:Mobile phones 二维树状数组
- POJ 1195:Mobile phones 二维树状数组
- OC类的封装(set和get方法)
- SQL Server之视图