洛谷P1831 槓桿數
阿新 • • 發佈:2018-12-13
數位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;
}