题意
传送门 POJ 3181
基本思路
优化递推式
结果 也会溢出,实现上使用大数运算。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f
#define delta 0.85
#define eps 1e-3
#define PI 3.14159265358979323846
#define MAX_L 40
#define MAX_K 105
#define MAX_N 1005
using namespace std;
struct bignum{
int limit;
int s[MAX_L];
bignum(){limit = 0; for(int i = 0; i < MAX_L; i++) s[i] = 0;}
void operator = (const bignum& other){
limit = other.limit;
for(int i = 0; i < MAX_L; i++) s[i] = other.s[i];
}
void operator += (const bignum& other){
int p = max(limit, other.limit);
for(int i = 0; i < p; i++){
s[i] += other.s[i];
if(s[i] >= 10) s[i] -= 10, s[i + 1]++;
}
limit = s[p] > 0 ? p + 1 : p;
}
void output(){
for(int i = limit - 1; i >= 0; i--) putchar(s[i] + '0');
putchar('\n');
}
}dp[MAX_K][MAX_N];
int N, K;
int main(){
dp[0][0].s[0] = dp[0][0].limit = 1;
for(int i = 1; i < MAX_K; i++){
for(int j = 0; j < MAX_N; j++){
dp[i][j] = dp[i - 1][j];
if(j >= i) dp[i][j] += dp[i][j - i];
}
}
while(~scanf("%d%d", &N, &K)){
dp[K][N].output();
}
return 0;
}