POJ1837 Balance 背包
题目大意: 有一个天平,天平左右两边各有若干个钩子,总共有C个钩子(每个钩子有相对于中心的距离,左负右正),有G个钩码,求将钩码全部挂到钩子上使天平平衡的方法的总数。
将每个砝码看作一组,组内各个物品的体积为每个挂钩与该砝码形成的力矩,背包总体积严格为0,这便是分组背包计数问题(特殊点:每一组必须出一个物品,而不是至多出一个物品)。由于c++不允许负的数组下标,所以每次更新时,j要加上offsetJ。
实现分组背包计数问题时,可以用填表法(找以前节点求自己值)(DP1)或刷表法(找以后节点更新以后值)(DP2)。由于刷表法时,如果DP[i][j]==0,可以跳过,所以节省时间。
注意:
- 不可以用一维数组倒序循环来表示DP数组,因为j-objV可能比j还大
- 同理,每次判断时,不是j-objV>=0,0代表天平的支点而不是左端点。所以应当为j-objV>=minJ。
#include <cstdio>
#include <cstring>
#include <cstdarg>
using namespace std; const int MAX_V = , MAX_OBJ = , MAX_HOOP = ;
const int Plus = ;
#define Sub(x) x+offsetJ
int TotHoop;
int Len[MAX_HOOP], W[MAX_OBJ]; void _printf(char *format, ...)
{
#ifdef _DEBUG
va_list(args);
va_start(args, format);
vprintf(format, args);
va_end(args);
#endif
} int DP1(int totHoop, int totDev, int *_w, int *_len)
{
int minJ = , maxJ = , wSum = , offsetJ, objV = ;
static int DP[MAX_OBJ][MAX_V];
for (int dev = ; dev <= totDev; dev++)
wSum += _w[dev];
for (int hoop = ; hoop <= totHoop; hoop++)
_len[hoop] > ? maxJ += _len[hoop] * wSum : minJ += _len[hoop] * wSum;
offsetJ = -minJ;
DP[][offsetJ] = ;
_printf("+ offsetJ %d maxJ %d\n", +offsetJ, maxJ);
for (int i = ; i <= totDev; i++)
for (int j = minJ; j <= maxJ; j++)
for (int hoop = ; hoop <= totHoop; hoop++)
{
objV = _w[i] * _len[hoop];
if (j - objV >= minJ && j - objV <= maxJ)
{
DP[i][j + offsetJ] += DP[(i - )][j + offsetJ - objV];
_printf("%d=DP[%d][%d] += DP[%d][%d]=%d\n", DP[i][j + offsetJ], i, j, i - , j - _w[i] * _len[hoop], DP[i - ][j - _w[i] * _len[hoop] + offsetJ]);
}
}
return DP[totDev][offsetJ];
} int DP2(int totHoop, int totDev, int *_w, int *_len)
{
int minJ = , maxJ = , wSum = , offsetJ, objV = ;
static int DP[MAX_OBJ][MAX_V];
for (int dev = ; dev <= totDev; dev++)
wSum += _w[dev];
for (int hoop = ; hoop <= totHoop; hoop++)
_len[hoop] > ? maxJ += _len[hoop] * wSum : minJ += _len[hoop] * wSum;
offsetJ = -minJ;
DP[][offsetJ] = ;
_printf("+ offsetJ %d maxJ %d\n", + offsetJ, maxJ);
for (int i = ; i < totDev; i++)
for (int j = minJ; j <= maxJ; j++)
if (DP[i][j+ offsetJ])
for (int hoop = ; hoop <= totHoop; hoop++)
{
objV = _w[i+] * _len[hoop];
DP[i + ][j + objV + offsetJ] += DP[i][j + offsetJ];
_printf("%d=DP[%d][%d] += DP[%d][%d]=%d\n", DP[i+][j+objV+ offsetJ], i+, j+objV+ offsetJ, i, j+ offsetJ , DP[i][j + offsetJ]);
}
return DP[totDev][offsetJ];
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totDevice, vCnt = , totV = , maxV = , minV = ;
scanf("%d%d", &TotHoop, &totDevice);
for (int i = ; i <= TotHoop; i++)
scanf("%d", i + Len);
for (int i = ; i <= totDevice; i++)
scanf("%d", i + W);
printf("%d\n", DP2(TotHoop, totDevice, W, Len));
return ;
}
POJ1837 Balance 背包的更多相关文章
- POJ1837 Balance[分组背包]
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13717 Accepted: 8616 Descript ...
- HDU 5616 Jam's balance 背包DP
Jam's balance Problem Description Jim has a balance and N weights. (1≤N≤20)The balance can only tell ...
- poj 1837 Balance(背包)
题目链接:http://poj.org/problem?id=1837 Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissi ...
- poj1837 Balance
Balance POJ - 1837 题目大意: 有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码,求将钩码全部挂到钩子上使天平平衡的方法的总数. 其中可以把天枰看做一个以x轴0点 ...
- poj1837【背包】
题意: 有一根杆子,给出一些杆子上的位置,位置上能放重物,再给出一些重物的重量. 重物都需要被使用,但是位置不一定都要用到. 问你能有多少种方法让这个杆子平衡. 思路: 在位置上是0/1背包思想,取或 ...
- poj1837 01背包(雾
Description A train has a locomotive that pulls the train with its many passenger coaches. If the lo ...
- POJ1837 Balance(DP)
POJ1837http://poj.org/problem?id=1837 题目大意就是说有一个称上有C个挂钩,告诉你每个挂钩的位置,现在有G个重物,求是之平衡的方法数. 转化一下:DP[i][j]表 ...
- poj 01背包
首先我是按这篇文章来确定题目的. poj3624 Charm Bracelet 模板题 没有要求填满,所以初始化为0就行 #include<cstdio> #include<algo ...
- POJ之01背包系列
poj3624 Charm Bracelet 模板题 没有要求填满,所以初始化为0就行 #include<cstdio> #include<iostream> using na ...
随机推荐
- java中强制类型转换时,高位数截取成低位数的方法
/** * 强制类型转换中的补码.反码.原码一搞清楚 */ int b=233;//正整数强转 System.out.println((byte)b); //负数:原码的绝对值取反再加一 符号为不变 ...
- C#之密封类(详解)
10.3 密封类与密封方法 如果所有的类都可以被继承,那么很容易导致继承的滥用,进而使类的层次结构体系变得十分复杂,这样使得开发人员对类的理解和使用变得十分困难,为了避免滥用继承,C#中提出了密封类 ...
- C# 对象克隆,DataTable转LIST
public class ConvertHelper<T> where T : new() { private static string module = "ConvertHe ...
- Spring Boot (4) 静态页面和Thymeleaf模板
静态页面 spring boot项目只有src目录,没有webapp目录,会将静态访问(html/图片等)映射到其自动配置的静态目录,如下 /static /public /resources /ME ...
- iOS-如何返回某个字符串的拼音助记码
我也是看了网上的一个示例代码后,在它的基础上进行的修改.因为项目上会用到,我相信很多人的项目上也会用到.所以实现后,也赶紧分享出来,希望后来人不需要花费时间了. 提示:这里用到了正则表达式,使用了一个 ...
- asp.net mvc学习入门
MVC是什么? M: Model就是我们获取的网页需要的数据 V: View就是我们的aspx页面,注意这是一个不包含后台代码文件的aspx页面.(其实带有.asp.cs文件也不会有编译错误,但是这样 ...
- cocos ios Label组件问题
软件:cocos creator v1.9.0 开发的过程中,一直在web上预览,Label组件显示一直没问题.在打包到ios上时,出现问题了: Label组件: 当我们缩小字体,发现没问题了,当我们 ...
- count(*)实现原理+两阶段提交总结
count(*)实现原理 不同引擎的实现: MyISAM引擎把表的总行数存在了磁盘上,执行COUNT(*)就会直接返回,效率很高: InnoDB在count(*)时,需要把数据一行一行的从引擎里面取出 ...
- Python基础(二)数据类型
(一)数字 Python3中的数字类型分为3种,分别是整型,浮点型以及复数. Python2种的数字类型分为4种,分别是整型,长整型,浮点型以及复数. 其中长整型时Python2为应对位数较大的而设置 ...
- C# 发起Get和Post请求
public class ApiHelper { //contentType application/json or application/xml public string HttpGet(str ...