to calculate the number of balanced numbers in a given range [x, y].
题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数
思路:按位枚举,找出所有可能的状况进行dfs,与POJ3252类似
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int bit[19]; __int64 dp[19][19][2005]; //pos为当前位置 //o为支点 //l为力矩 //work为是否有上限 __int64 dfs(int pos,int o,int l,int work) { if(pos == -1) return l == 0;//已经全部组合完了 if(l<0)//力矩和为负,则后面的必然小于0 return 0; if(!work && dp[pos][o][l]!=-1)//没有上限,且已经被搜索过了 return dp[pos][o][l]; __int64 ans = 0; int end = work?bit[pos]:9;//有上限就设为上限,否则就设为9 for(int i=0; i<=end; i++) { int next = l; next += (pos-o)*i;//力矩 ans+=dfs(pos-1,o,next,work&&i==end); } if(!work) dp[pos][o][l] = ans; return ans; } __int64 solve(__int64 n) { int len = 0; while(n) { bit[len++] = n%10; n/=10; } __int64 ans = 0; for(int i = 0; i<len; i++) { ans+=dfs(len-1,i,0,1); } return ans-(len-1);//排除掉0,00,000....这些情况 } int main() { int T; __int64 l,r; scanf("%d",&T); memset(dp,-1,sizeof(dp)); while(T--) { scanf("%I64d%I64d",&l,&r); printf("%I64d\n",solve(r)-solve(l-1)); } return 0; }