题意:平衡数问题,就是找一个支点,两边位上的数成力矩和相等
比如 4139 以3作为支点 左边=4*2+1*1 = 右边=9*1
思路:
一开始没想到,一点就恍然大悟。
dp[site][n][sum] n为支点。
然后只要枚举支点就好了。
然后减去00,000,0000这些情况就ok了
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"stack" #include"algorithm" #include"iostream" using namespace std; __int64 dp[22][22][2500]; int num[22]; __int64 dfs(int site,int zd,int sum,int f) { if(sum<0) return 0; //小优化 和为负数可以返回了 因为不可能再变正 if(site==0) return !sum; if(!f&&dp[site][zd][sum]!=-1) return dp[site][zd][sum]; int len=f?num[site]:9; __int64 ans=0; for(int i=0;i<=len;i++) { ans+=dfs(site-1,zd,sum+i*(site-zd),f&&i==len); } if(!f) dp[site][zd][sum]=ans; return ans; } __int64 solve(__int64 x) { __int64 ans=0; int cnt=0; while(x) { num[++cnt]=x%10; x/=10; } for(int i=1;i<=cnt;i++) ans+=dfs(cnt,i,0,1); return ans-cnt+1; //减去00,000,这些重复的 } int main() { int t; cin>>t; memset(dp,-1,sizeof(dp)); while(t--) { __int64 x,y; scanf("%I64d%I64d",&x,&y); printf("%I64d\n",solve(y)-solve(x-1)); } return 0; }
时间: 2024-10-26 03:07:27