POJ 1837 Balance 动态规划

POJ 1837 Balance 动态规划

思路:

力矩 = 力臂*重量。这个高中物理学过啦,呵呵。
所以如果现在有一个 3 放在 -5 的位置上,一个 4 放在 3 的位置上,那当前天平的总力矩就是 3*-5 + 4*3 = -3 了

动态规划:
从小到大依次放 weight。
f[i][j] = { 已经放了 i 个 weight,天平的总力矩为 j 时候的方案个数 }
初始化 f[0][0] = 1
状态转移:
对每个位置 x
   f[i + 1][j + W[i + 1]*x] += f[i][j]

#include  < stdio.h >
#include 
< stdlib.h >

int  C, G, X[ 24 ], W[ 24 ];
struct   {
    
int val, tm;
}
 _dp[ 2 ][ 1   <<   15 ],  * dp[ 2 =   {
    
&_dp[0][_countof(_dp[0]) / 2],
    
&_dp[1][_countof(_dp[1]) / 2],
}
* cur,  * pre;
int  up, down;

int  main()
{
    
int i, j, k, y;

    freopen(
"e:\\test\\in.txt""r", stdin);

    scanf(
"%d%d"&C, &G);
    
for (i = 1; i <= C; i++)
        scanf(
"%d"&X[i]);
    
for (i = 1; i <= G; i++)
        scanf(
"%d"&W[i]);

    dp[
1][0].tm = 1;
    dp[
1][0].val = 1;
    
for (i = 1; i <= G; i++{
        pre 
= dp[i & 1];
        cur 
= dp[(i + 1& 1];
        
for (j = down; j <= up; j++{
            
if (pre[j].tm != i)
                
continue;
            
for (k = 1; k <= C; k++{
                y 
= j + W[i]*X[k];
                
if (cur[y].tm != i + 1{
                    cur[y].tm 
= i + 1;
                    cur[y].val 
= 0;
                }

                cur[y].val 
+= pre[j].val;
                
if (y < down)
                    down 
= y;
                
if (y > up)
                    up 
= y;
            }

        }

    }

    printf(
"%d\n", cur[0].val);
    

    
return 0;
}

你可能感兴趣的:(POJ 1837 Balance 动态规划)