#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m;
int p[25], w[25];
int f[25][15005];
struct poj1837 {
/*
* 【问题描述】:
* n和m分别表示钩子数和砝码数,p[]表示每个钩子到支点的距离(负值代表钩子在左端),w[]表示每个砝码的重量,
* 要求所有砝码都要用上,求有多少种方案可以使得天平左右平衡
*/
/*
* 【解题思路】:
* 问题规模是砝码个数和“平衡值”,定义状态(n,value)表示用前n个砝码,得到平衡值为value的方法数
* 其中value=sum(w[i]*p[ki]),1<=i<=n,ki表示第i个砝码放的位置
* f(n, value)+=f(n-1,value-w[n]*p[kn])(第n个砝码可以选择放置的位置,这和01背包问题是类似的)
* 因为value的最小值为-7500,所以定义value'=value+7500
*
* [递推式]:f(n, value')+=f(n-1,value'-w[n]*p[kn])
* [边界条件]:f(0, 7500)=1
*/
void work() {
while (cin >> n >> m) {
for (int i = 1; i <= n; i++)
cin >> p[i];
for (int i = 1; i <= m; i++)
cin >> w[i];
memset(f, 0, sizeof(f));
f[0][7500] = 1;
for (int i = 1; i <= m; i++) {
for (int j = 0; j <= 15000; j++) {
for (int k = 1; k <= n; k++) {
if (j - w[i] * p[k] >= 0) {
f[i][j] += f[i - 1][j - w[i] * p[k]];
}
}
}
}
cout << f[m][7500] << endl;
}
}
};
int main()
{
poj1837 solution;
solution.work();
return 0;
}
poj1837-Balance(01背包)
最新推荐文章于 2022-05-13 10:40:30 发布