#include<stdio.h>
#include<iostream>
using namespace std;
int n,k,f[400][7][100];
int d(int l,int m,int n){
int sum=0;
if(f[l][m][n]>0) return f[l][m][n];
else if(m<=0||n>l) return f[l][m][n]=0;
else if(m==1&&l>=n) return f[l][m][n]=1;//不能再取了(m==1)
else{
for(int i=n;i<=l;i++){//事实上我们每次尝试做 从l中取数(取i)
sum+=d(l-i,m-1,i);//依次从最小(n)到最大(l)尝试取数,取了可取次数就减一(m-1)
}
return f[l][m][n]=sum;
}
}
int main(){
cin>>n>>k;
cout<<d(n,k,1);
return 0;
}
题解:记忆化搜索,d(l,m,n) 表示划分l成为m份其中最小值为n。
d(l,m,n)=sum{ d( l-i , m-1 , i ) | n < = i < = l }