标签:
问题可以转化成,对于二进制的每一位,每位最多用k次,那么能加出n的情况数,
这样其实就一个背包问题,利用记忆化搜索,减少需要的状态数
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MOD = 1000000009;
int w[20];
int t, n, k;
int dp[20][10005];
int solve(int u, int sum) {
if (u > 17) return 0;
if (dp[u][sum] != -1) return dp[u][sum];
dp[u][sum] = 0;
if (sum == 0) return dp[u][sum] = 1;
int s = sum;
for (int i = 0; i <= k; i++) {
dp[u][sum] = (dp[u][sum] + solve(u + 1, s)) % MOD;
s -= w[u];
if (s < 0) break;
}
return dp[u][sum];
}
int main() {
w[0] = 1;
for (int i = 1; i < 20; i++) w[i] = w[i - 1] * 2;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &k, &n);
memset(dp, -1, sizeof(dp));
printf("%d\n", solve(0, n));
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/accelerator_/article/details/44806981