数位DP神题(至少我是这样认为的)
说一下抄来的思路
我们先假设平衡位置在第一位(最左边),然后算出现在的总代价,然后我们再枚举其他位置时的贡献差
自己模拟一下平衡位置右移过程中的变化,假设i是第p位且在现在的平衡点k的右侧,之前的贡献是i*(p-k+1),现在是i*(p-k),差值是一个i所以+i,反之亦然是-i,然后就没了
代码
//By AcerMo
#include
#include
#include
#include
#include
#define lli long long int
using namespace std;
lli l,r,e;
lli lim[55],f[55][6000];
inline lli dfs(int p,lli sum,bool jud)
{
if (!p) return sum;
if (!jud&&f[p][sum]!=-1) return f[p][sum];
lli ans=0;int emm=jud?lim[p]:e-1;
for (int i=0;i<=emm;i++)
ans+=dfs(p-1,sum+i*(p-1),jud&&(i==emm));
if (!jud) return f[p][sum]=ans;
return ans;
}
inline lli sub(int p,lli sum,int k,bool jud)
{
if (sum<0) return 0;
if (!p) return sum;
if (!jud&&f[p][sum]!=-1) return f[p][sum];
lli ans=0;int emm=jud?lim[p]:e-1;
for (int i=0;i<=emm;i++)
if (p>=k) ans+=sub(p-1,sum+i,k,jud&&(i==emm));
else ans+=sub(p-1,sum-i,k,jud&&(i==emm));
if (!jud) return f[p][sum]=ans;
return ans;
}
inline lli slove(lli x)
{
int len=0;
while (x) lim[++len]=x%e,x/=e;
memset(f,-1,sizeof(f));
lli ans=dfs(len,0,1);
for (int i=2;i<=len;i++)
{
memset(f,-1,sizeof(f));
ans-=sub(len,0,i,1);
}
return ans;
}
signed main()
{
cin>>l>>r>>e;
cout<