hdu3709 Balanced Number 数位DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709

题目大意就是求给定区间内的平衡数的个数

要明白一点:对于一个给定的数,假设其位数为n,那么可以有n个不同的位作为支点,但每次只能有一个支点

定义dp[len][pos][k],len表示当前还需处理的位数,pos表示当前的所选的支点的位置,k表示计算到当前的力矩之和(即从最高位到第len+1位)

容易知道如果在某一个len>1的位置k已经小于0,那么就可以直接剪枝

代码如下 :

 #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;
int bit[];
long long int dp[][][];
long long int x,y; long long int dfs(int len,int pos,int sum,bool flag )
{
long long int ans=;
if(len== ) return sum==;
if(sum<) return ;
if(flag && dp[len][pos][sum]>=) return dp[len][pos][sum]; int tmp=flag?:bit[len]; for(int i=;i<=tmp;i++)
{
int n_sum=sum;
n_sum+=i*(len-pos);
ans+=dfs(len-,pos,n_sum,flag||i<tmp);
}
if(flag) dp[len][pos][sum]=ans;
return ans;
}
long long int solve(long long int n)
{
int len=;
while(n) bit[++len]=n%,n/=;
long long int ans=;
for(int i=;i<=len;i++)
{
ans+=dfs(len,i,,);
} return ans-(len-); }
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%64d %64d",&x,&y);
memset(dp,-,sizeof(dp));
cout<<solve(y)<<endl; }
return ;
}
上一篇:linux学习笔记30--网络命令ifconfig


下一篇:Django学习笔记(5)——cookie和session