前身题
此题将之前代码的或者符号改成加号
暴力递归:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int a[20];
int fun(int n,int M){ //当前为结尾凑成的最少张数;
if(M==0)
return 1;
else if(n==0){
if(M==a[0])
return 1;
else
return 0;
}
else if(a[n]>M)
return fun(n-1,M);
else{
return fun(n-1,M)+fun(n-1,M-a[n]); //将或者符号改成加号
}
}
int main(){
int M,n;
M=40;
while(cin>>n){
for(int i=0;i<n;i++)
cin>>a[i];
cout<<fun(n-1,M)<<endl;
}
return 0;
}
记忆性递归:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int a[20];
int dp[25][45];
int fun(int n,int M){ //当前为结尾凑成的最少张数;
if(dp[n][M]>=0)
return dp[n][M];
int ans;
if(M==0)
ans = 1;
else if(n==0){
if(M==a[0])
ans = 1;
else
ans = 0;
}
else if(a[n]>M)
ans = fun(n-1,M);
else{
ans = fun(n-1,M)+fun(n-1,M-a[n]);
}
dp[n][M]=ans;
return ans;
}
int main(){
int M,n;
M=40;
while(cin>>n){
memset(dp,-1,sizeof dp);
for(int i=0;i<n;i++)
cin>>a[i];
cout<<fun(n-1,M)<<endl;
}
return 0;
}

这篇博客主要介绍了如何使用递归和记忆化搜索两种方法解决组合问题。在暴力递归中,通过修改代码将或者符号替换为加号,实现了从一组数中找出所有可能的组合,使得组合的总和等于目标值。记忆化递归通过保存中间计算结果,避免了重复计算,提高了效率。代码示例分别展示了这两种方法的实现,并在主函数中读取输入数据并输出结果。
49

被折叠的 条评论
为什么被折叠?



