[DP] poj1837

/*题目意思是给你一个balance, 共有C个位置, G个砝码, 问你总共有多少种方法使balance左右平衡(每一种方法中砝码都要用完)。 状态方程dp[i][j] 表示使用前i个砝码, 不平衡数为j的方法数(j>0 表示右边比左边重j,j < 0表示左边比右边重j) 显然j的范围是-15*25*20 到 15*25*20 即[-7500, 7500]。于是可以得到状态转移方程, dp[i][j] += dp[i-1][j-C[k]*G[i]] ( i: 1...G j: -7500...7500 k: 1....C,C[k]表示第k个挂钩的位置, G[i]表示第i个砝码的重量)。 */

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[21][15001] = { 0 };
int
main()
{ // freopen("in.txt","r",stdin);
  int C, N, P[27], W[27];
  int i, j, k;
  while (scanf("%d%d", &C, &N) != EOF) {
    int Mw = 0, Min = 1 << 29, Max = -(1 << 29);
    for (i = 1; i <= C; i++)
      scanf("%d", &P[i]), Min = min(Min, P[i]), Max = max(Max, P[i]);
    for (i = 1; i <= N; i++)
      scanf("%d", &W[i]), Mw = max(Mw, W[i]);
    dp[0][7500] = 1;
    for (i = 1; i <= N; i++)
      for (k = 1; k <= C; k++) {
        int dlta = W[i] * P[k];
        for (j = Mw * Min * 20 + 7500; j <= Mw * Max * 20 + 7500; j++) {
          dp[i][j] += dp[i - 1][j - dlta];
        }
      }
    cout << dp[N][7500] << endl;
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值