您的位置:首页 > 其它

POJ 1837 Balance (枚举状态的01背包)

2013-02-13 15:43 351 查看
题目大意:有个天平,给定G个不同大小的力,C个天平两边的力臂,求把所有力放在力臂上后天平平衡的方案数.

我很难从这道题中找到一般DP那样的最优子结构,所以这类问题也就需要我们来“枚举”所有的情况了.

一般情况下需要枚举状态的DP,我们会设bool f[i][j]表示某种状态存不存在。而这道题要求方案数,所以,

我们设f[i][j]表示前i种物品平衡度为j的方案数.并且因为存在负的平衡度,所以我们给他扩大一倍->15000.

初始f[0][7500] = 1(7500表示平衡度为0)

状态转移方程即为:f[i][j] += f[i-1][j-l[k]*w[i]]

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef long long LL;
LL f[30][20000];
int l[30], w[30];
int main(){
int C, G;
scanf("%d%d", &C, &G);
for (int i = 0; i < C; i ++)
scanf("%d", &l[i]);
for (int i = 0; i < G; i ++)
scanf("%d", &w[i]);
for (int i = 0; i < 30; i ++)
for (int j = 0; j < 20000; j ++)
f[i][j] = 0;
f[0][7500] = 1;
for (int i = 1; i <= G; i ++){
for (int j = 0; j < 15000; j ++){
for (int k = 0; k < C; k ++)
if (j - l[k]*w[i] >= 0)
f[i][j] += f[i-1][j-l[k]*w[i-1]];
}
}
printf("%I64d\n", f[G][7500]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: