直接暴力dfs就可以了,就是注意枚举上下限的选择,以及怎样避免重复枚举(一开始没想到)
将所分解的数按递增的排列,就不用标记是否枚举过,直接都是不重复的分解情况
数据范围小可以直接暴力
#include<iostream>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<string>
#include<cstdio>
#include<set>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e6+10;
typedef long long ll;
int n,k,cnt;
void dfs(int last,int sum,int cur)
//last 枚举的数,sum 总数和,cur 分解的个数
{
if(cur==k)
{
if(sum==n) cnt++;
return;
}
for(int i=last;sum+i*(k-cur)<=n;i++)
//剪枝,只用枚举到sum+i*(k-cur)<=n为止
//递增枚举减少重复,剪枝优化不能大于(sum-n)/(k-cur)
dfs(i,sum+i,cur+1);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
dfs(1,0,0);
cout<<cnt<<endl;
}