Balance
Time Limit: 1000MS
Memory Limit: 30000K
Total Submissions: 13525
Accepted: 8474

Description

Gigel has a strange "balance" and he wants to poise it. Actually, the device is different from any other ordinary balance. 

It orders two arms of negligible weight and each arm's length is 15. Some hooks are attached to these arms and Gigel wants to hang up some weights from his collection of G weights (1 <= G <= 20) knowing that these weights have distinct values in the range 1..25.
Gigel may droop any weight of any hook but he is forced to use all the weights. 

Finally, Gigel managed to balance the device using the experience he gained at the National Olympiad in Informatics. Now he would like to know in how many ways the device can be balanced. 



Knowing the repartition of the hooks and the set of the weights write a program that calculates the number of possibilities to balance the device. 

It is guaranteed that will exist at least one solution for each test case at the evaluation. 

Input

The input has the following structure: 

• the first line contains the number C (2 <= C <= 20) and the number G (2 <= G <= 20); 

• the next line contains C integer numbers (these numbers are also distinct and sorted in ascending order) in the range -15..15 representing the repartition of the hooks; each number represents the position relative to the center of the balance on the X axis
(when no weights are attached the device is balanced and lined up to the X axis; the absolute value of the distances represents the distance between the hook and the balance center and the sign of the numbers determines the arm of the balance to which the
hook is attached: '-' for the left arm and '+' for the right arm); 

• on the next line there are G natural, distinct and sorted in ascending order numbers in the range 1..25 representing the weights' values. 

Output

The output contains the number M representing the number of possibilities to poise the balance.

Sample Input

2 4
-2 3
3 4 5 8

Sample Output

2

题目大意:给定一个天平,然后给定位置和一定数量的砝码,问有多少种方法能够使得天平达到平衡(注意:给定的砝码每一种只有一个,但是需要全部用完)

样例:2 4//第一个数代表有两个地方可以挂载砝码,4代表有4个砝码

-2 3//两个挂载位置,-2代表在天平左侧距离天平中心长度为2的地方,3代表在天平右侧距离天平中心长度为3的地方

3 4 5 8//分别代表4个砝码的质量

解题思路:

PS:参考了大神的思路(●'◡'●)

首先找出两个维度,第一维度为第几个砝码"i",第二个维度是天平的平衡度"j"。其中平衡度<0代表向左侧倾斜,平衡度>0代表向右侧倾斜,==0代表符合题目叙述要求。假设全部砝码挂在一端的外侧,那么最大的平衡度=15(天平臂长)*20(砝码数量)*25(最重的砝码数量)=7500。左侧为-7500,右侧为7500。避免负数带来的麻烦,整体偏移7500,得到0-15000,其中7500就是代表的原来的平衡位置。

再考虑状态转移方程,用dp[i][j]代表当挂第i个砝码时,平衡度能够达到j所产生的方法的数目。同时力矩=臂长*重量。

所以当dp[i][j]确定的时候,他能够向后影响dp[i+1][j+c[k]*w[i+1]]

注意:这里的k小标代表的是输入数据中的挂载位置,因为位置的不同,所以实际上dp[i][j]产生了k个影响。

那么站在任意一个dp[i+1][j+c[k]*w[i+1]]的情况来说,dp[i][j]为它产生了多少种新的方法呢?当然是dp[i][j]种,

即在原有的基础上增加了dp[i][j]种,就有dp[i+1][j+c[k]*w[i+1]]+=dp[i][j];

如果是dp[i-1][j]对dp[i][j+c[k]*w[i]]呢?同理,得到dp[i][j+w[i]*c[k]]+=dp[i-1][j];

所以,状态转移方程就是dp[i][j+w[i]*c[k]]+=dp[i-1][j]当然也可以刚开始推到的那一种,为了使用方便起见,用这一个,其实一样。

记得仔细想一想无向后性...

源代码:

<span style="font-size:24px;">#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
using namespace std; int dp[21][15001];
int main() {
int i, j, k;//控制变量的下标
int n, g;
int c[21], w[21];
memset(dp,0,sizeof(dp));
dp[0][7500] = 1;//不放砝码时平衡度为7500至少有一种方法,初始化
scanf("%d%d",&n,&g);//位置个数,砝码的个数
for(i = 1; i <= n; i++) {
scanf("%d",&c[i]);
}
for(j = 1; j <= g; j++) {
scanf("%d",&w[j]);
}
for(i = 1; i <= g; i++) {
for(j = 0; j <= 7500*2; j++) {
//因为砝码所处位置的不同,所以需要再写for循环加和,才能够得到对应
//受到影响的dp[i][j+w[i]*c[k]],一个dp[i-1][j]产生n个影响
for(k = 1; k <= n; k++) {
dp[i][j+w[i]*c[k]]+=dp[i-1][j];
}
}
}
printf("%d\n",dp[g][7500]);//最后结果保存在dp[g][7500]中
return 0;
} </span>

POJ1837--二维背包的更多相关文章

  1. 二维背包(钟神想要的)(不是DP)

    [问题描述] 背包是个好东西,希望我也有.给你一个二维的背包,它的体积是? × ?.现在你有一些大小为1× 2和1×3的物品,每个物品有自己的价值.你希望往背包里面装一些物品,使得它们的价值和最大,问 ...

  2. hdu 4501 小明系列故事——买年货_二维背包

    题目:你可以有v1元,v2代金券,v3个物品免单,现在有n个商品,商品能用纸币或者代金券购买,当然你可以买v3个商品免费.问怎么最大能买多少价值 题意: 思路二维背包,dp[v1][v2][v3]=M ...

  3. HDU 2159 FATE (二维背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 解题报告:这题实际上是一个二维的背包问题,也可以由01背包扩展而来,01背包用一维数组,可想而知 ...

  4. rqnoj-329-刘翔!加油!-二维背包

    注意排除干扰项. 因为价值不会相等,所以价值的多少与本题没有任何关系,. 所以价值为干扰项,所以不用考虑. 二维背包,简单求解. #include<stdio.h> #include< ...

  5. NOI 4978 宠物小精灵之收服(二维背包)

    http://noi.openjudge.cn/ch0206/4978/ 描述 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事. 一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物 ...

  6. dp之二维背包poj2576

    题意:有一群sb要拔河,把这群sb分为两拨,两拨sb数只差不能大于1,输出这两拨人的体重,小的在前面...... 思路:把总人数除2,总重量除2,之后你会发现就是个简单的二维背包,有两个限制..... ...

  7. hdu 3496 Watch The Movie (二维背包)

    Watch The Movie Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  8. 二维背包---P1509 找啊找啊找GF

    P1509 找啊找啊找GF 题解 很明显这是一道二维背包题目 如果一个dp数组做不了,那么我们就再来一个dp数组 题目要求,花费不超过 m ,消耗人品不超过  r  ,泡到尽量多的妹子,时间尽量少 f ...

  9. 二维背包---P1855 榨取kkksc03

    P1855 榨取kkksc03 题解 二维背包板子题 f[ i ][ j ] 前 n 个物品,花费金钱不超过 i ,花费时间不超过 j 的最大价值 如果每个物品只能选一次,那么就相当于在01背包上多加 ...

  10. 01二维背包——poj2576

    /* 要求把a数组分成两个集合,两个集合人数最多差1,并且元素之和的差尽可能小 那只要把所有可行的列出来即可 01二维背包,即体积是个二维数据,那么我们的背包状态也应该设为二维 dp[j][k]设为 ...

随机推荐

  1. Linux系统EXT文件系统

    分区格式化(Linux创建文件系统):(假设需要格式化的分区为/dev/sdb1) 1. ext2文件系统和ext3文件系统的区别: ext2不支持日志文件系统,不会产生日志文件,ext3则会产生日志 ...

  2. 基于容器微服务的PaaS云平台设计(二)通过kubernetes实现微服务容器管理

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://www.cnblogs.com/SuperXJ/ 上一章描述了基于spring cloud的微服务实例(实 ...

  3. python字符串,列表,字符串,元组,集合的一些方法

    字符串方法 __contains__ #等同in name = 'erroy' result = name.__contains__('er') #判断元素是否包含er print(result) T ...

  4. YYHS-猜数字(并查集/线段树维护)

    题目描述     LYK在玩猜数字游戏.    总共有n个互不相同的正整数,LYK每次猜一段区间的最小值.形如[li,ri]这段区间的数字的最小值一定等于xi.     我们总能构造出一种方案使得LY ...

  5. 借助csv用PHP生成excel文件

    当你将xml文件改为csv后缀会发现原先的表格结构都变成用逗号隔开的一行一行数据,就像这样 编号,姓名,年龄 001,王宇,28 002,刘三,20 由此看来,如果能将PHP数据输出为这样的格式,然后 ...

  6. Xilinx ISE 14.1中模拟True Dual Port RAM例子

    <一>创建工程 创建工程在此略过. <二>基本代码 1.创建一个Verilog modual代码如下: module main( input clk, input rsta, ...

  7. Air Raid

    Air Raid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  8. Scala从入门到精通之四-映射和元组

    在Scala中映射之键值对的集合,元组是n个对象的聚集,但是对象的类型不一定相同 本节内容要点 Scala中映射的创建,遍历和查询 如何从可变和不可变映射中做出选择 Scala映射和Java映射见的互 ...

  9. PTA 循环单链表区间删除 (15 分)

    本题要求实现带头结点的循环单链表的创建和单链表的区间删除.L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于m ...

  10. 【2】hadoop搭建准备软件

    准备一:VMware虚拟工具: 链接:http://pan.baidu.com/s/1o7F4A6I 密码:w5ti 准备二:CentOS6.8虚拟机(64位):如果64位不允许安装,可能是电脑设置问 ...