数的划分
考虑不重复,所以升序记录每一次划分,注意到可以进行最优性剪枝,当
s
u
m
+
i
∗
(
k
−
c
u
r
)
>
n
sum+i*(k-cur)>n
sum+i∗(k−cur)>n(因为枚举的数是递增的,枚举了当前数之后还要
(
k
−
c
u
r
)
(k-cur)
(k−cur)个比
i
i
i还大的数,如果在
i
i
i的时候已经不合法了后面也一定不合法)时,当前枚举的已经不合法了可以停止搜索了。
因为当前值直接是在
d
f
s
dfs
dfs状态里,所以回溯的时候不用对
c
u
r
,
s
u
m
cur,sum
cur,sum的值进行操作。
#include <bits/stdc++.h>
using namespace std;
int n,k,tot;
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<1)+(cnt<<3)+(c^48);c=getchar();}
return cnt*f;
}
void dfs(int now,int sum,int cur){
if(cur==k) {if(sum==n) ++tot;return;}
for(int i=now;sum+i*(k-cur)<=n;++i){
dfs(i,sum+i,cur+1);
}
}
signed main(){
n=read(),k=read();
dfs(1,0,0);
cout<<tot<<endl;
return 0;
}