hdu 3709 Balanced Number 2010成都区域赛 数位dp
来源:互联网 发布:有关大数据的例子 编辑:程序博客网 时间:2024/04/30 15:09
题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709
题目来源:2010成都区域赛,之前存在手里的题目。
简要题意:定义平衡数,选取一位为平衡点,其向两边距离和位的乘积的加和相等。
4139 选取3 为平衡点则4×2+1×1=9=9×1 ,是平衡数。
求 [l,r] 间平衡数的个数。数据范围:
0<T⩽30;0⩽l,r⩽1018
题解
看到题目可以想到应该是道数位dp,开始的时候,一直在考虑将和保存到下标里,可是这样递推就不知道每位的和了,再加一位,然后因为最后发现变得极其复杂,因为还需要考虑平衡点是空出来的。
最后发现网上的做法极其简洁,不是考虑让两边的和相等,而是前面减后面的等于
0 。更进一步地,发现如下规律:
令
x=akak−1⋯a1(ak>0) 为十进制的展开。可以发现令piv为平衡点,定义f(x,piv)=∑i=1k(i−piv)×ai f(x,piv)=0 是选取piv 为平衡点时x 为平衡数的充要条件。从中我们也可以发现:
即除非每位都是f(x,piv+1)=f(x,piv)+∑i=1kai(piv<k) 0 ,固定了x 后这个函数随着piv 严格单调变化的。那么对于一个
x 只有一个piv 可以让它成为平衡数。我们可以记录对于一个长度
piv 在哪个,f(x,piv) 为多少的有多少个。然后去找每个长度
f(x,piv)=0 的个数,减去0 中重复的情况得到答案。
实现
经过思路上的化简之后,题目变得相当简洁,注意要减去
0 重复的情况还有当前和小于0 可以直接退出。
代码
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headLL dp[25][25][2005];int num[25];LL dfs(int pos, int piv, bool e, int cursum) { if (pos == 0) return cursum == 0; if (cursum < 0) return 0; if (!e && dp[pos][piv][cursum] != -1) return dp[pos][piv][cursum]; int lim = e ? num[pos] : 9; LL ans = 0; for (int i = 0; i <= lim; i++) { ans += dfs(pos-1, piv, e&&i==lim, cursum+(pos-piv)*i); } if (!e) dp[pos][piv][cursum] = ans; return ans;}LL solve(LL x) { if (x <= 0) return x+1; int len = 0; while (x) { num[++len] = x%10; x /= 10; } LL ans = 0; for (int i = len; i >= 1; i--) { ans += dfs(len, i, true, 0); } return ans-len+1;}int main(){ memset(dp, -1, sizeof dp); int t; scanf("%d", &t); while (t--) { LL l, r; scanf("%I64d%I64d", &l, &r); printf("%I64d\n", solve(r)-solve(l-1)); } return 0;}
0 0
- hdu 3709 Balanced Number 2010成都区域赛 数位dp
- HDU 3709 Balanced Number(数位DP)
- 数位dp HDU 3709 Balanced Number
- hdu 3709 Balanced Number (数位dp)
- hdu 3709 Balanced Number(数位dp)
- Balanced Number - HDU 3709 数位dp
- [数位dp] hdu 3709 Balanced Number
- 【HDU】3709 Balanced Number 数位DP
- HDU 3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number(数位DP)
- 【数位DP】 HDU 3709 Balanced Number
- hdu 3709Balanced Number(数位dp)
- HDU 3709 Balanced Number (简单数位DP)
- HDU 3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number (数位dp)
- 数位DP-HDU-3709-Balanced Number
- HDU 3709 Balanced Number(数位dp)
- HDU 3709 Balanced Number(数位dp)
- Server 2012 搭建 VPN
- 碎碎念-360小时
- 整数中1出现的次数(从1到n整数中1出现的次数)(算法)
- 格雷码Java
- 1095. Cars on Campus (30)
- hdu 3709 Balanced Number 2010成都区域赛 数位dp
- ffmpeg for android error
- centos 6.6升级自带mysql版本文档
- 安装RPM套件rpm-build错误解决:NOKEY、elfutils is needed
- 一个由泛型和Auto Unbox引发的Crash
- AVPlayer 和 MPMoivePlayerController的区别
- 机器学习基石学习笔记3 VC Dimension(1)
- 解决Win10 Windows10关键错误 开始菜单和Cortana无法工作问题
- 1096. Consecutive Factors (20)