https://www.acwing.com/problem/content/1373/
1、暴搜写法超时
1 #include<iostream> 2 using namespace std; 3 const int N=30; 4 int a[N]; 5 int v,n; 6 int res=0; 7 void dfs(int sum,int now){ 8 if(sum>=n){ 9 if(sum==n){ 10 res++; 11 } 12 return; 13 } 14 for(int i=now;i<v;i++){ 15 // sum+=a[i]; 16 dfs(sum+a[i],i); 17 } 18 } 19 int main(void){ 20 cin>>v>>n; 21 for(int i=0;i<v;i++){ 22 cin>>a[i]; 23 } 24 dfs(0,0); 25 cout<<res; 26 return 0; 27 }
2、抽象为完全背包问题
1 #include<iostream> 2 using namespace std; 3 typedef long long LL; 4 const int N=30; 5 LL f[N][10010]; 6 int main(void){ 7 int v,n; 8 cin>>v>>n; 9 f[0][0]=1; 10 for(int i=1;i<=v;i++){ 11 int t; 12 cin>>t; 13 for(int j=0;j<=n;j++){ 14 f[i][j]=f[i-1][j]; 15 for(int k=1;k<=j/t;k++){ 16 f[i][j]+=f[i-1][j-k*t]; 17 } 18 } 19 } 20 cout<<f[v][n]; 21 return 0; 22 }
3、完全背包问题优化
1 #include<iostream> 2 using namespace std; 3 typedef long long LL; 4 const int N=30; 5 LL f[N][10010]; 6 int main(void){ 7 int v,n; 8 cin>>v>>n; 9 f[0][0]=1; 10 for(int i=1;i<=v;i++){ 11 int t; 12 cin>>t; 13 for(int j=0;j<=n;j++){ 14 f[i][j]=f[i-1][j]; 15 if(j>=t) f[i][j]+=f[i][j-t]; 16 } 17 } 18 cout<<f[v][n]; 19 return 0; 20 }
优化为一维空间
1 #include<iostream> 2 using namespace std; 3 typedef long long LL; 4 const int N=30; 5 LL f[10010]; 6 int main(void){ 7 int v,n; 8 cin>>v>>n; 9 f[0]=1; 10 for(int i=1;i<=v;i++){ 11 int t; 12 cin>>t; 13 for(int j=0;j<=n;j++){ 14 if(j>=t) f[j]+=f[j-t]; 15 } 16 } 17 cout<<f[n]; 18 return 0; 19 }