1. 程式人生 > >洛谷P1831 槓桿數

洛谷P1831 槓桿數

數位DP

區間求符合條件的數的個數,不出意外應該是記搜大法好了2333 我們列舉平衡點,然後最後判斷兩側數是否相等就行了 我們定義dfs(int p,int w,int s,bool j,bool z) 分別表示第p位,平衡點在第w位,當前和為s,是否有數位限制,是否有前導零 然後我們就可以大力搜尋了,s的更新是s+(p-w)*i發現平衡點兩側的p-w符號不同,然後剪枝,當s<0時,return 0,因為以後不可能加成非負數

程式碼

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include
<iostream>
#include<algorithm> #define lli long long int using namespace std; lli lim[20],f[20][20][3050]; inline lli dfs(int p,int w,int s,bool j,bool z) { if (!p) return (z==0&&s==0); if (s<0) return 0; if (!j&&f[p][w][s]!=-1) return f[p][w][s]; int emm=j?lim[p]:9;lli ans=
0; for (int i=0;i<=emm;i++) ans+=dfs(p-1,w,s+i*(p-w),j&&(i==emm),z&&(i==0)); if (!j&&!z) f[p][w][s]=ans; return ans; } inline lli slove(lli x) { int len=0; while (x) lim[++len]=x%10,x/=10; memset(f,-1,sizeof(f)); lli ans=0; for (int i=1;i<=len;i++) ans+=dfs(len,i,0,1,
1); return ans; } signed main() { lli l,r;cin>>l>>r; cout<<slove(r)-slove(l-1); return 0; }