3 20 20 20
3
枚举,最大2^20.
递归:
#include <iostream>
using namespace std;
int a[30]; int N;
int Ways(int w ,int k ) { // 从前k种物品中选择一些,凑成体积w的做法数目
if( w == 0 ) return 1;
if( k <= 0 ) return 0;
return Ways(w, k -1 ) + Ways(w - a[k], k -1 );
}
int main() {
cin >> N;
for( int i = 1;i <= N; ++ i )
cin >> a[i];
cout << Ways(40,N);
return 0;
}#include <iostream>
using namespace std;
int a[30]; int N;
int Ways[40][30];//Ways[i][j]表示从前j种物品里凑出体积i的方法数
int main() {
cin >> N;
memset(Ways,0,sizeof(Ways));
for( int i = 1;i <= N; ++ i ) {
cin >> a[i]; Ways[0][i] = 1;
}
Ways[0][0] = 1;
for( int w = 1 ; w <= 40; ++ w ) {
for( int k = 1; k <= N; ++ k ) {
Ways[w][k] = Ways[w][k-1];
if( w-a[k] >= 0) Ways[w][k] += Ways[w-a[k]][k-1];
}
}
cout << Ways[40][N]; return 0;
}
#include <iostream>
using namespace std;
#define MAX 41
int main(){
int n,i,j,input; int sum[MAX];
for(i=0;i<MAX;i++) sum[i]=0;
cin >> n;
for(i=0;i<n;i++){
cin >> input;
for(j=40;j>=1;j--)
if(sum[j]>0 && j+input <= 40)
sum[j+input] += sum[j];
//如果j有sum[j]种方式可达,则每种方式加上input就可达 j + input
sum[input]++;
}
cout << sum[40] << endl;
return 0;
}对于sum[j+input] += sum[j];实际指对于所有满足sum[j]>0 && j+input <= 40在原有的sum[j+input]基础上增加sum[j],不断累积n次。另外,sum[input]++的原因是什么呢???
很容易想到sum[input]++就是存储input下标位置的值,那么为什么不能直接也和其他数一样通过sum[input] += sum[0];来得到呢,当我们把j最小设为0不是可以么?也许会有人觉得是这样,但请回头看清题意,物品的体积范围是1-40,也就是说sum[0]恒为0不会发生改变,倘若不特殊处理,那么每次input下标所对应的位置都将少1.
原文地址:http://blog.csdn.net/u014492609/article/details/40826811