算法:poj 1837 Balance (dp 01背包)

题目大意:

有一个天平,天平左右两边的手臂长度都是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<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define SQ(x) ((x)*(x))
#define MP make_pair
const 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<n; ++i)
            scanf("%d", &pos[i]);  

        for(int i=0; i<m; ++i)
            scanf("%d", &w[i]);  

        memset(f, 0, sizeof(f));
        f[0][mid] = 1;  

        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){  

                int add = w[i]*pos[j];
                for(int v=mid*2; v-add>=0; --v){
                    if(v-add <= mid*2)
                        f[i+1][v] += f[i][v-add];
                }
            }
        }
        printf("%d\n", f[m][mid]);
    }
    return 0;
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索算法
, 题目
, 长度
背包
new balance背包、背包dp、dp背包问题、戴森dp01、em dp01,以便于您获取更多的相关知识。

时间: 2024-10-26 05:32:34

算法:poj 1837 Balance (dp 01背包)的相关文章

算法:poj 3211 Washing Clothes(01背包)

题目大意: Dearboy和他的女朋友一起洗m件衣服,共有n总颜色(每件衣服只有一种颜色). 为 了放置不同颜色互染,每次只能洗一种颜色的衣服,在这件衣服洗完之前不能洗另外一种衣服. Dearboy和 他女朋友可以同时一起洗衣服,但是不能同时洗同一件衣服,也不能同时洗不同种颜色的衣服. 一 只每件衣服所需时间,问最少花费多少时间可以全部洗完. 分析: 首先可以很直观的判定, 一定是把一种颜色的所有衣服都洗完再接着洗另外一种颜色的衣服,洗每种颜色所有衣服的总时间是分开独 立的. 关键是洗同一种颜色

算法:hdu 2639 Bone Collector II (dp 01背包求第k优解)

题目大意: 有n件物品,每件物品有体积和价值两个属性, 一个小偷带着一个大小为v的背包,要 偷这些东西,问小偷能偷的第k大的价值是多少? 思路: 这题和典型的01背包求最优解不同, 是要求第k大的解,所以,最直观的想法就是在01背包的基础上再增加一维,用来保存前k大小的数,然后在 递推时,根据前一个状态的前k 大小的数推出下一个阶段的前k个数保存下来. d[i][j][k], 表示取前i个物品,用j的费用,第k大价值是多少 在递推d[i][j][1...k]时,先获取上一个状态d[i- 1][j

算法:poj 2063 Investment (dp 完全背包)

题目大意: 有n种债券可以买,每种的价钱分别为a(a是1000的倍数),每年利息为b .某个人 共有钱tot(tot是1000的倍数),问他在y年后,最多可以有多少钱? 思路: 由于tot和a都 是 1000的倍数,所有在计算时可以把他们缩小1000倍,这样节约内存和时间. 按照贪心的思想,每 一年都用完全背包求出这一年最大可以得到的利息,然后下一年再用加上利息后的总钱继续计算下去-- 代码: #include<iostream> #include<queue> #include&

算法:POJ 2184 Cow Exhibition (dp 转换01背包)

题目大意: 有N个物品,每个物品有属性Si和Fi,-1000 <= Si, Fi <= 1000, 每种物品最 多只能选一次,问怎样选使得物品的所有Si和Fi属性之和最大,并且要求Si之和与Fi之和都不能下于 0. 思路: 这题想了很久都没思路,于是跟前辈请教了下,恍然大悟.把属性Si当做是物品的 费用,Fi当做是价值,然后做01背包即可. 代码: #include<iostream> #include<queue> #include<stack> #inc

算法:poj 3628 Bookshelf 2(dfs, 01背包)

题目大意: 有n个数字(1-100W),现在有一个数b,1<=b<=s(s为n个数字之和).要从n 个数字中选择一些数字组合,有一写组合的数字之和x会大于等于b, 求所有x中x-b最小的是多少? 思路: 刚开始看到这题,发现数字这么大,以为内存不够不能用背包.而n最大才20,所以直接用 dfs+减枝0MS过了... 然后用背包,开了2000W+的数组,memset初始化,果断地MLE了...然后 看了下discuss,发现用memset会增加很多额外的内存. 于是改用for循环初始化,内存就够

算法:poj 2923 Relocation (枚举+背包 | 状态压缩+01背包)

题目大意: 有N件家具,每件的重量为(1 ≤ wi ≤ 100), 用两辆车把他们来运送到目的地.这 两辆车的限载重量分别为C1, C2(1 ≤ Ci ≤ 100) , 问最少几趟可以把所有家具运送到目的地. 这两辆车每趟都必须一起走,即使某辆车没载东西. 思路: (一) 先上自己的方法: 枚举第一辆车可能载的家具的所有组合情况,那么用二进制来表示状态则共有 1<<n ,如果 二进制的第i位上是1,那么就表示第i件家具是由第一辆车运的. 这样就相当于把所有家具分成了两 组,一组给第一辆车运,另

优化-01背包回溯法计算起来非常慢,有木有算法大大帮忙看看

问题描述 01背包回溯法计算起来非常慢,有木有算法大大帮忙看看 #include #include #include #include #include #include using namespace std; int n;//物品数量 double c;//背包容量 double v[9000];//各个物品的价值 double w[9000];//各个物品的重量 double cw = 0.0;//当前背包重量 double cp = 0.0;//当前背包中物品价值 double best

01背包相关问题c语言算法设计课程设计

问题描述 01背包相关问题c语言算法设计课程设计 一.设计题目 0/1背包问题 问题描述:一个商人带着一个能够装m千克的背包去乡下收购货物,准备将这些货物卖的城里获利.现有n种货源,且知道第i种货物有Wi千克,可获得Pi元,收购那些货物以获得最大利润.(在选择装入背包时,对每种货物只有两种选择,即装入背包,或不装入背包,货物不允许拆零) 二.设计主要内容 具体要求如下: (1) 使用蛮力算法实现 (2) 使用递归算法实现 (3) 使用动态规划算法实现 (4) 对各种算法的时间复杂度进行分析和比较

hdu3339 In Action(Dijkstra+01背包)

/* 题意:有 n 个站点(编号1...n),每一个站点都有一个能量值,为了不让这些能量值连接起来,要用 坦克占领这个站点!已知站点的 之间的距离,每个坦克从0点出发到某一个站点,1 unit distance costs 1 unit oil! 最后占领的所有的站点的能量值之和为总能量值的一半还要多,问最少耗油多少! */ /* 思路:不同的坦克会占领不同的站点,耗油最少那就是路程最少,所以我们先将从 0点到其他各点的 最短距离求出来!也就是d[i]的值!然后我们又知道每一个站点的所具有的能量