博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1837 Balance (dp 01背包)
阅读量:4072 次
发布时间:2019-05-25

本文共 1172 字,大约阅读时间需要 3 分钟。

题目:

题目大意:

有一个天平,天平左右两边的手臂长度都是15,手臂上面有些位置会有挂钩。还有G个砝码 (1 <= G <= 20),它们重量各不相同,在1~25中取值。

给出C个挂钩,它们的位置在【-15..15】,不会重叠。负号的代表在左边臂,正号的在右边。

要求把所有砝码都放在挂钩上,多个砝码可以挂在同一个挂钩上,问有多少种不同的方案使天平能够平衡?

思路:

天平左臂的力矩和是负数,右边的力矩和是正数,那么左边+右边的力矩之和,如果是正数,代表天平平衡倾向右边,负数代表倾向左边,为0的时候天平是平衡的。我们把 “左边力矩和+右边力矩和”叫做平衡系数

状态f[i][j]代表用前i个砝码,放置成平衡系数为j的时候共有多少种方案。
那么,f[i][j] += f[i-1][j-C[k]*G[i]],  {0<=k=<c};
因为平衡系数中有负数的,所以要所有平衡系数往右平移,即加上一个足够大的正数。可以计算出力矩之和最小负数的是把所有砝码都挂在天平-15的位置上,砝码最多20个,取值最大的情况是6...25,那么砝码之和最终为 (6+25)*20/2 = 310, 力矩之和为 -15*310 = 4650
所以加上4650即可,这是位置4650代表的是原来天平的中间位置,
初始化 f[0][4650] = 1, 表示一个砝码都不挂,这是一种平衡的方案。

最终,f[G][4650]就是答案。

PS: 这题最开始我是用滚动数组做的,用G++提交一直RE到死,郁闷。后来改用C++提交就可以AC了。

代码:

#include
#include
#include
#include
#include
#define SQ(x) ((x)*(x))#define MP make_pairconst int INF = 0x3f3f3f3f;const double PI = acos(-1.0);typedef long long int64;using namespace std;const int MAXN = 22;const int mid = 4650;int pos[MAXN], w[MAXN];int f[22][mid*2+10];int n, m;int main(){ while(~scanf("%d%d", &n, &m)){ for(int i=0; i
=0; --v){ if(v-add <= mid*2) f[i+1][v] += f[i][v-add]; } } } printf("%d\n", f[m][mid]); } return 0;}

转载地址:http://epzni.baihongyu.com/

你可能感兴趣的文章
12个Flex常用功能代码
查看>>
addChild一个.swf时,该swf的背景色失效,同时如有超出大小的范围,也会显示,造成边距...
查看>>
MovieClip,Sprite,Shape三者之间的区别
查看>>
欣赏ActionScript 3 的元件架构
查看>>
在as3中只有事件(或该事件的子级)的发送者才能侦听事件
查看>>
rotation的单位是角度
查看>>
所谓速度就是每次移动比上次移动的距离多一点
查看>>
Flex Develpment中右边的框的linkWithEdit
查看>>
不兼容的签名实现和函数默认参数
查看>>
不兼容的签名实现,
查看>>
字体轮廓和设备字体
查看>>
水平和垂直翻转可视对象
查看>>
1.随机函数,计算机运行的基石
查看>>
MouseEvent的e.stageX是Number型,可见as3作者的考虑
查看>>
在mc中直接加aswing组件,该组件还需最后用validate()方法
查看>>
社区设计细节 : 用户可选是否在新窗口中打开主题
查看>>
Memcache是什么?
查看>>
Eclipse和FlexBuilder中设置编辑代码高亮
查看>>
移植Vim配色方案到Eclipse
查看>>
xml解析
查看>>