题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598
数位DP...东看西看:http://www.cnblogs.com/Artanis/p/3751644.html
https://www.cnblogs.com/MashiroSky/p/6399095.html
好巧妙的思路啊!这样统计的东西就变得很简单了;
好美的 dfs!数位DP用 dfs 好像能变得很清楚。
代码如下:
#include#include #include using namespace std; typedef long long ll; ll l,r,f[65][6005],ans; int n,a[65],K; ll dfs1(int pos,int s,bool lim) {if(pos==0)return s;if(!lim&&f[pos][s]!=-1)return f[pos][s];int end=K-1; ll ret=0;if(lim)end=a[pos];for(int i=0;i<=end;i++)ret+=dfs1(pos-1,s+i*(pos-1),lim&&(i==end));if(!lim)f[pos][s]=ret;//!lim!return ret; } ll dfs(int pos,int s,int m,bool lim) {if(s<0)return 0;//!if(pos==0)return s;if(!lim&&f[pos][s]!=-1)return f[pos][s];int end=K-1; ll ret=0;if(lim)end=a[pos];for(int i=0;i<=end;i++){if(pos>=m)ret+=dfs(pos-1,s+i,m,lim&&(i==end));else ret+=dfs(pos-1,s-i,m,lim&&(i==end));}if(!lim)f[pos][s]=ret;return ret; } ll calc(ll x) {int n=0;while(x)a[++n]=x%K,x/=K;memset(f,-1,sizeof f);ll ret=dfs1(n,0,1);for(int i=2;i<=n;i++){memset(f,-1,sizeof f);ret-=dfs(n,0,i,1);} return ret; } int main() {scanf("%lld%lld%d",&l,&r,&K);printf("%lld ",calc(r)-calc(l-1));return 0; }