数位dp练习
题意
求 0−n中有多少个数在 k进制下和 −k 进制 下的表示方式一样,
举个例子, 4的−3进制表示为 4=(121)-3=1×(−3)2+2×(−3)1+1×(−3)0
题解
可以发现这个性质,所有符合条件的数,奇数次幂的位上的数为0。
根据性质,数位dp即可
code
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; typedef long long LL; const int N = 1100; LL dp[N],a[N],pw[N]; int p,c; LL n,k; void init(LL k) { LL tmp = 1; pw[0] = 1; for (int i=1; i<=100; ++i) { tmp = tmp * k; if (tmp < 0) break; pw[++p] = tmp; } } LL dfs(int pos,bool limit,bool limit2) { if (pos == c+1) return 1; if (!limit && dp[pos]!=-1) return dp[pos]; int u; if (limit2) u = 0; else u = limit?a[pos]:k-1; LL ret = 0; for (int i=0; i<=u; ++i) { ret += dfs(pos+1,limit&&i==a[pos],!limit2); } if (dp[pos]==-1) dp[pos] = ret; return ret; } void work(LL n) { bool fir = false; for (int i=p; i>=0; --i) { LL ts = pw[i]; if (n >= pw[i]) { fir = true; a[++c] = n/pw[i]; n = n % pw[i]; } else if (fir) a[++c] = 0; } memset(dp,-1,sizeof(dp)); cout<<dfs(1,true,c%2==0); // 是c!!!,不是p!!! } int main() { n,k; cin>>n>>k; init(k); work(n); return 0; }
by zhx p107 终末