hdu 3709 Balanced Number 数位dp
2015-12-10 17:50
134 查看
题目链接
一个数称为平衡数, 只要他的某一位满足, 这一位左边的所有数sigma x*(x距离这一位的距离)等于右边的sigma x*(x距离这一位的距离), 例如4139, 3就满足这个性质, 因为4*2+1*1 == 9*1。
求出一个范围内的平衡数的数量。
看起来好麻烦, 不好想状态, 但是我们可以枚举每一位作为支点, 这样问题就简化了许多。具体看代码
一个数称为平衡数, 只要他的某一位满足, 这一位左边的所有数sigma x*(x距离这一位的距离)等于右边的sigma x*(x距离这一位的距离), 例如4139, 3就满足这个性质, 因为4*2+1*1 == 9*1。
求出一个范围内的平衡数的数量。
看起来好麻烦, 不好想状态, 但是我们可以枚举每一位作为支点, 这样问题就简化了许多。具体看代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define mem1(a) memset(a, -1, sizeof(a)) ll dp[20][20][4000], digit[20]; ll dfs(int len, int center, int sum, bool fp) { if(!len) { return sum==0; } if(!fp&&dp[len][center][sum]!=-1) //center是支点, sum是和 return dp[len][center][sum]; ll maxx = fp?digit[len]:9, ret = 0; for(int i = 0; i<=maxx; i++) { ret += dfs(len-1, center, sum+i*(center-len), fp&&i==maxx); } if(!fp) return dp[len][center][sum] = ret; return ret; } ll cal(ll n) { int len = 0; while(n) { digit[++len] = n%10; n/=10; } ll ret = 0; for(int i = 1; i<=len; i++) { ret += dfs(len, i, 0, 1); //枚举每一位 } return ret-(len-1); //因为每次计算了len个0, 而我们只需要一个0 } int main() { ll a, b, t; mem1(dp); cin>>t; while(t--) { scanf("%I64d%I64d", &a, &b); printf("%I64d\n", cal(b)-cal(a-1)); } }
相关文章推荐
- android ListView的使用 (一)
- cocos2d js 给sprite增加按钮点击事件
- 文件上传 webuploader
- 通过环境变量修改jvm内存
- Linux下安装JDK
- find grep 组合使用
- Java知识点
- test知识
- 初识 Spark
- listview下拉刷新上拉加载扩展(一)
- Hibernate List集合
- linux设置开机自启动的三种方法
- Android开发中这些小技巧你都知道吗?(四)
- listview下拉刷新上拉加载扩展(一)
- 【Html】CSS浮动(float,clear)通俗讲解
- ModernDriven 获得表单数据
- 一个ListView中显示不同的item(分组)
- 1、IOS学习计划
- jmeter之命令行模式(Non-GUI Mode )
- Linux Redis安装部署操作指南(一)