POJ 1837 Balance

解题思路: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次有关,因此可以缩减为二维数组

NULL
   
     
#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 ;
}

 

你可能感兴趣的:(poj)