POJ1837 动态规划 (01背包)
来源:互联网 发布:网络防雷保护器 编辑:程序博客网 时间:2024/06/05 20:57
好了!开始干DP。
话说我已经预感到我dp会弱到一定程度了。预计会先持续干两天的dp。
题目概述:
这道题目是说现在有一个神奇的天平,你的目的是要令他平衡。天平两边长度均为15,每边最多有20个挂钩,一共提供最多20个砝码,要求计算当所有砝码都挂上的时候,能使天平平衡的悬挂方式一共有多少种呢。
算法思想:
不得不承认,即使知道这是一个01背包的题,开始做的时候仍然是不会的,然后找题解,看了好长时间看懂之后自己敲了一遍之后ac。
大意是dp[i][j]的意义是在放进第i个砝码之后,达到平衡值j的可能悬挂方式有多少种。
所谓平衡值,就是以7500为平衡点,左移或者右移动(因为左右移动的最大量为7500,所以设置为7500是刚好不会越界)。
然后dp[i][j]就只跟dp[i][j-g[i]*c[k]]有关了,具体关系是dp[i][j]就是把所有组合的g[i]*c[k]组合起来。这里注意i代表第i个砝码,k代表第k个钩子,因为和两个变量都有关,应该是没有办法把这个01背包转换为一维数组(如果有的话还请教导)。直接做也当然没有问题。
代码部分:
#include <iostream>#include <string.h>using namespace std;int nc, ng;int dp[21][15001]; // dp[i][j]数组,意义为在放入第i个重物之后,所能达到的平衡状态量 // 这里把负数的量也加上了,7500等价于平衡,7500以上相当于右边重,以下相当于左边重int c[21], g[21];int main() {cin >> nc >> ng;for (int i = 1; i <= nc; i++) {cin >> c[i];}for (int i = 1; i <= ng; i++) {cin >> g[i];}memset(dp, 0, sizeof(dp));dp[0][7500] = 1; // 初始化的意义,在没有重物放上的时候,自然为一个方法,初始化为1for (int i = 1; i <= ng; i++) {for (int j = 0; j <= 15000; j++) {if (dp[i - 1][j]) { // 如果之前这种状态不存在,不用计数for (int k = 1; k <= nc; k++) {dp[i][j + c[k] * g[i]] += dp[i - 1][j];}}}}cout << dp[ng][7500] << endl;return 0;}
0 0
- POJ1837 动态规划 (01背包)
- poj1837 动态规划和01背包问题延伸的经典题目,很值得一做
- POJ1837 Balance(动态规划)
- poj1837动态规划
- poj1837(01背包)
- POJ1837:Balance(01背包)
- POJ1837:Balance(01背包)
- poj1837--01背包
- poj1837(01背包)
- POJ1837-Balance(01背包)
- POJ1837 动态规划 天平问题
- 算法の动态规划poj1837
- 动态规划 01背包
- 01背包-动态规划
- 01背包动态规划
- 01背包 动态规划
- 01背包动态规划
- 01背包 动态规划
- 超简单使用MemCached
- 朝鲜RedStar_OS_3.0安装图解
- 如何将.class文件反编译为.java文件
- 通过http post发送json数据
- 图片加水印c#
- POJ1837 动态规划 (01背包)
- Activity 自定义dialog (自定义layout)
- mysql 存储过程
- kernel tasklets, and work queues
- Android Shape自定义纯色圆角按钮
- SQL Server调优系列进阶篇(如何维护数据库索引)
- Eclipse 快捷键 查找关联文件
- Cocos2dx-Lua:360滑动操作杆
- 听刘老讲产品经理第一课