前身题
此题将之前代码的或者符号改成加号
暴力递归:
#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;
}