HDU 3709 Balanced Number 数位dp
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3709
Balanced Number
Memory Limit: 65535/65535 K (Java/Others)
样例输出
10
897
题意
求区间[L,R]内的一类平衡数,平衡数定义:存在一个数位,它两侧的力矩想等。 比如4139,存在数位3,有
4*2+1*1=9*1
。
题解
数位dp,这题如果状态想对的话非常好写。
dp[i][j][sum]表示支点为j,前i位力矩和为sum的情况数。特性:对于大于0的平衡数,支点有且只有一个,且如果考虑相对于支点的位差为每一位位权,所有位权和为0,如:
4139有sum=4*2+1*1+3*0+9*(-1)=0
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=22;
int arr[maxn],tot;
LL dp[maxn][maxn][1805];
///ismax标记表示前驱是否是边界值
LL dfs(int len,int j, int sum,bool ismax) {
if(sum<0) return 0;
if (len == 0) {
if(sum==0) return 1;
else return 0;
}
if (!ismax&&dp[len][j][sum]>=0) return dp[len][j][sum];
LL res = 0;
int ed = ismax ? arr[len] : 9;
///这里插入递推公式
for (int i = 0; i <= ed; i++) {
res += dfs(len - 1, j, sum+(len-j)*i,ismax&&i == ed);
}
return ismax ? res : dp[len][j][sum] = res;
}
LL solve(LL x) {
tot = 0;
while (x) { arr[++tot] = x % 10; x /= 10; }
LL ret=0;
for(int j=1;j<=tot;j++){
ret+=dfs(tot,j,0,true)-1;
}
return ret+1;
}
int main() {
clr(dp,-1);
int tc;
scf("%d",&tc);
while(tc--){
LL x,y;
scf("%I64d%I64d",&x,&y);
LL ans;
if(x>0) ans=solve(y)-solve(x-1);
else ans=solve(y);
prf("%I64d\n",ans);
}
return 0;
}
//end-----------------------------------------------------------------------
Notes
这题关键的支点的性质想到了,但是状态少想了一个,发现很难转移,对于dp这种东西,如果时间,空间允许,状态越高维,问题应该会相对越好转移。
要发现引起你状态无法转移的变量,然后把它作为定值去枚举它!!!!!!!!!!!!!!!!!!