poj-1837

来源:互联网 发布:人工智能计算器电脑版 编辑:程序博客网 时间:2024/05/21 05:38
Balance
     题意:第一行输入两个数C和G。C表示天平上有几个挂钩,G表示有几个挂码。第二行输入C个挂钩的位置,负数表示在左侧,正数表示在右侧。第三行输入G个挂码的重量。问有几种方法可以使得天平平衡。
    要使天平平衡需要左右两端的力矩相同,左右力矩最大值都为20*15*25=7500。把每一个力矩值都作为一个状态,则一侧一共有7500个状态,由于左侧的力矩为0~-7500,所以将状态表示整体增大7500。所以力矩的状态为0~15000,7500时表示左右平衡。达到每种状态时的方案数,与使用的砝码数量有关,所以需要从只有1个挂码到有G个挂码的状态层层转移。
     因此可以类似背包问题的方法求解,有状态转移方程dp[i][j+w[i]*v[k]] += dp[i-1][j];,表示当有前i个砝码时,,即第i个砝码是新加入的,砝码i悬挂的位置用k表示有1~C个。我们计算出每种状态j+w[i]*v[k]下的方案数。初始化0个砝码时,到达平衡状态7500时的方案数为1。
     AC的代码如下:
#include<iostream>#include<cstring>using namespace std;int dp[21][15010];int main(){int C,G;int v[26],w[26];cin >> C >> G;for(int i=1;i<=C;i++){cin >> v[i];//挂钩位置 }for(int i=1;i<=G;i++){cin >> w[i];//挂物重量 }memset(dp,0,sizeof(dp));dp[0][7500] = 1;for(int i=1;i<=G;i++){for(int j=1;j<=15000;j++){for(int k=1;k<=C;k++)    {    dp[i][j+w[i]*v[k]] += dp[i-1][j];    }}}cout << dp[G][7500] << endl;return 0;}