第一次用比较复杂的写法,需要把DP数组初始化放在多组里边,无论怎么优化也TLE。看完题解之后,发现可以通过思路转化,很巧妙的把初始化放在外面,可以使多组数据同时使用DP数组。以后遇到DP题目,可以用不同的DP表示,效率上可能会相差甚远。
DP[i][j]表示后i位,和小于等于j的方案数。
知道DP的状态表示后,就很简单啦。
AC代码:
/*
* @Author: hesorchen
* @Date: 2020-12-30 15:48:28
* @LastEditTime: 2021-01-19 21:24:24
* @Description: 栽种绝处的花
*/
#include <bits/stdc++.h>
using namespace std;
long long a[12], b[12];
long long dp[12][4600];
long long maxn;
long long dfs(long long pos, long long limit, long long now)
{
if (pos == 0)
return 1;
if (!limit && dp[pos][maxn - now] != -1)
return dp[pos][maxn - now];
long long up = limit ? b[pos] : 9;
long long sum = 0;
for (int i = 0; i <= up; i++)
{
if (now + (1 << (pos - 1)) * i > maxn)
break;
sum += dfs(pos - 1, limit && up == i, now + (1 << (pos - 1)) * i);
}
if (!limit)
dp[pos][maxn - now] = sum;
return sum;
}
long long get(long long A, long long B)
{
maxn = 0;
long long ct = 1;
while (A)
{
maxn += (A % 10) * ct;
ct *= 2;
A /= 10;
}
long long pos = 0;
while (B)
{
b[++pos] = B % 10;
B /= 10;
}
return dfs(pos, 1, 0);
}
int main()
{
long long t, CA = 0;
cin >> t;
memset(dp, -1, sizeof dp);
while (t--)
{
long long A, B;
scanf("%lld %lld", &A, &B);
printf("Case #%lld: %lld\n", ++CA, get(A, B));
}
return 0;
}