您的位置:首页 > 其它

POJ 1837 Balance (简单DP)

2015-10-05 14:06 405 查看

题目大意

一架天平,天平上有m个钩子,有n个砝码(2 <= c <= 20,2 <= G <= 20),天平的坐标范围为[-15,15]。

给出m个钩子的坐标c[i](-15<=c<=15),以及n个砝码的重量g[j](1 <= g <= 25),要求所有砝码都要用到,求最终平衡的方案数

分析

dp[i][j] 表示对于前i个砝码,在平衡度为j时的方案数

最大平衡度maxn = 15 * 20 * 25 = 7500。即[-7500,7500],为了方便处理,右移7500,即[0,15000]。所以平衡度为7500时,天平保持平衡。

对于每个砝码都有m种方法,所以时间复杂度为O(m*n*V)。V为最大平衡度,即15000

状态转移方程: dp[i][j+g[i]*c[k]] += d[i-1][j],初始化dp[0][7500] = 1。

代码

#include <iostream>
#include <cstring>

using namespace std;
const int maxn = 15000;
int dp[30][maxn+10]; //dp[j]表示前i个砝码,在平衡度为j时的方案数
int c[maxn] , g[maxn];

int main()
{
int m , n;
while(cin >> m >> n)
{
for(int i = 1; i <= m; i++) cin >> c[i];
for(int i = 1; i <= n; i++) cin >> g[i];
memset(dp , 0 , sizeof(dp));
dp[0][7500] = 1; //两边都不放砝码时

//dp[i][j+c*g] += dp[i][j]
for(int i = 1; i <= n; i++) for(int j = maxn; j >= 0; j--) if(dp[i-1][j]) {
for(int k = 1; k <= m; k++) {
dp[i][j+c[k]*g[i]] += dp[i-1][j];
//cout << "dp[" << i << "]" << "[" << j+c[k]*g[i] << "] = " << dp[i][j+c[k]*g[i]] << endl;
}

}
cout << dp
[7500] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp