附:完全背包问题板子题链接
一维
#include <iostream>
using namespace std;
const int maxn=10010;
int n,W;
int s[maxn];
long long dp[maxn];// 方案数很大使用long long
int main(){
cin>>n>>W;
for(int i=1; i<=n; i++)cin>>s[i];
dp[0]=1;//赋初值
for(int i=1; i<=n; i++){
for(int j=s[i]; j<=W; j++){
dp[j]+=dp[j-s[i]];
}
}
cout<<dp[W];
return 0;
}
二维
#include <iostream>
using namespace std;
const int maxn=10010;
int n,W;
int s[maxn];
long long dp[30][maxn];//注意开dp[maxn][maxn]会runtime error
int main(){
cin>>n>>W;
for(int i=1; i<=n; i++)cin>>s[i];
dp[1][0]=1; //只需要赋一个初值
for(int i=1; i<=n; i++){
for(int j=0; j<=W; j++){
dp[i][j]+=dp[i-1][j];
if(j>=s[i])dp[i][j]+=dp[i][j-s[i]];
}
}
cout<<dp[n][W];
return 0;
}
dfs,听说可以记忆化搜索,我不会。。
下面是爆搜代码会TLE
#include <iostream>
using namespace std;
const int maxn=10010;
int n,W;
int ans=0;//答案
int s[maxn];
void dfs(int index, int w){
if(w==0){//递归边界
ans++;
return;
}
if(w<0||index>n){//递归边界
return;
}
dfs(index, w-s[index]);//当前层搜索
dfs(index+1, w);//下一层
}
int main(){
cin>>n>>W;
for(int i=1; i<=n; i++)cin>>s[i];
dfs(1,W);
cout<<ans;
return 0;
}
记忆化搜索其实就是,将每次递归的结果 使用dfs参数作为下标存起来,然后遇到相同下标的时候将存起来的结果返回