题目https://www.luogu.com.cn/problem/P1025
解法1:深度优先搜素
准确来说是 DFS + 最优性剪枝。
我们在上一次选择的数字之后的范围进行枚举,记录这次选择的结果。
优化:记录之前的选择的数字之和,我们记为 ,那么枚举的范围为 。
记录的是选择的数字。
如果顺利地枚举完了每一位数字,那么累加答案。
实现
#include<bits/stdc++.h>
using namespace std;
int n,k,ans,a[205];
void dfs(int x,int sum){
if(x>k){
ans+=(sum==n);
return;
}
if(sum>n){
return;
}
for(int i=a[x-1];i<=n-sum;i++){
a[x]=i;
dfs(x+1,sum+i);
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>k;
a[0]=1;
dfs(1,0);
cout<<ans;
return 0;
}
解法2:动态规划
设 表示数字 划分为 组有多少种方案数。
按照我们的状态设立,答案就是 。
记得初始时 。
实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,dp[205][15];
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
dp[i][1]=1;
for(int j=2ll;j<=min(i,m);j++){
dp[i][j]=(dp[i-1][j-1]+dp[i-j][j]);
}
}
cout<<dp[n][m];
return 0;
}
标签:洛谷,NOIP2001,int,题解,sum,枚举,ans,return,数字
From: https://blog.csdn.net/ATION001/article/details/145328260