题目:
考察知识点:数位DP
思路:
套用记忆化的数位DP模板( 凌乱之风--数位DP(DFS) )数位DP模板 。记录 当前位置 和 当前位置之前 1 的个数
,要注意所有位都为 0 的情况,搜到最后一位 return 时和 1 取一个最大值,以免 0 * res 对结果造成影响。
代码:
数位DP ( times:9ms )
#include <bits/stdc++.h>
using namespace std;
const int N = 55, mod = 10000007;
#define int long long
int dp[N][N];
int a[N];
int n;
int dfs(int pos, int sum, int limit)
{
if (!pos)
{
return max(sum, (int)1);
}
if (!limit && dp[pos][sum] != -1)
return dp[pos][sum];
int res = 1, up = limit ? a[pos] : 1;
for (int i = 0; i <= up; i++)
{
(res *= dfs(pos - 1, sum + (i == 1), limit && i == up)) %= mod;
}
return limit ? res : dp[pos][sum] = res;
}
int cal(int x)
{
memset(dp, -1, sizeof dp);
int len = 0;
while (x)
a[++len] = x % 2, x /= 2;
return dfs(len, 0, 1);
}
signed main()
{
cin >> n;
cout << (cal(n)) << endl;
return 0;
}