解题思路:DP
g[i]表示第i个砝码的重量,c[j]表示第j个点的坐标,opt[i][k]表示加了i个砝码,力矩之和为k的方法数
DP公式为(考虑到力矩为负,因此需要做偏移):
opt[i + 1 ][k + g[i] * c[j] += opt[i][k]
第i次迭代只于i-1次有关,因此可以缩减为二维数组
#include < iostream >
using namespace std;
#define MID 4875
#define MAXN 9751
int main()
{
int i,j,k,m,n,t, * x, * y, * z,c[ 20 ],g[ 20 ],a[MAXN],b[MAXN];
scanf( " %d %d " , & m, & n);
for (i = 0 ;i < m;i ++ )scanf( " %d " , & c[i]);
for (i = 0 ;i < n;i ++ )scanf( " %d " , & g[i]);
memset(a, 0 , sizeof (a));
a[MID] = 1 ,x = a,y = b;
for (i = 0 ;i < n;i ++ )
{
for (j = 0 ;j < MAXN;j ++ )y[j] = 0 ;
for (j = 0 ;j < m;j ++ )
for (t = g[i] * c[j],k = 0 ;k < MAXN;k ++ )
if (x[k])y[k + t] += x[k];
z = x,x = y,y = z;
}
printf( " %d\n " ,x[MID]);
return 0 ;
}