http://poj.org/problem?id=1837
是参考网上的,所以,01背包不要单纯的局限在max,min上。
陋见:关键应该是找到最后要输出的那个东西(比如这里的f【m】【7500】),知道答案会保存在这样一个数里后,而且根据经验知道这个下标一般都是最大的数也就是m,即积累到这里。而这题因为是平衡,所以输出的这个数一定是坐标轴的原点——>所以想怎样表示平衡位置(即0-----7500-----15000)。所以知道要设二维数组,使最后输出f[m][7500]。之前考虑过数组里的数存w[]*d[],但是这个作为数组下标后,那数组里保存的数就应该是以1为公差累加的。所以推出动归方程。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 int w[25],d[25],f[25][16000]; 8 int main() 9 { 10 int n,m; 11 while(scanf("%d%d",&n,&m)!=EOF) 12 { 13 for(int i=1;i<=n;i++) 14 scanf("%d",&w[i]); 15 for(int i=1;i<=m;i++) 16 scanf("%d",&d[i]); 17 f[0][7500]=1; 18 for(int i=1;i<=m;i++) 19 { 20 for(int j=0;j<=15000;j++) //7500=25*20*15 21 if(f[i-1][j]) 22 { 23 for(int k=1;k<=n;k++) 24 f[i][j+w[k]*d[i]]+=f[i-1][j]; 25 } 26 } 27 printf("%d ",f[m][7500]); 28 } 29 return 0; 30 }