【dp 背包变形】 poj 1837

#include <cstdio>
#include <memory.h>
#include<iostream>
using namespace std;
int dp[21][15001]; //状态数组dp[i][j]
int main(int i,int j,int k)
{
 int n;  //挂钩数
 int g;  //钩码数
 int c[21];  //挂钩位置
 int w[21];  //钩码重量
 cin>>n>>g;
 for(i=1;i<=n;i++)
  cin>>c[i];
 for(i=1;i<=g;i++)
  cin>>w[i];
 memset(dp,0,sizeof(dp));  //达到每个状态的方法数初始化为0
 dp[0][7500]=1;     //7500为天枰达到平衡状态时的平衡度
 for(i=1;i<=g;i++)
  for(j=0;j<=15000;j++)
   if(dp[i-1][j])  //优化
    for(k=1;k<=n;k++)
                    if(j+w[i]*c[k]<15001)
     dp[i][ j+w[i]*c[k] ] += dp[i-1][j]; //状态方程
 cout<<dp[g][7500]<<endl;
 return 0;
}
时间: 2024-10-07 11:13:49

【dp 背包变形】 poj 1837的相关文章

poj 1837 01背包

Balance Time Limit: 1000 MS Memory Limit: 30000 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Gigel has a strange "balance" and he wants to poise it. Actually, the device is different fr

poj 1837 Balance (dp,01背包)

链接:poj 1837 题意:有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码, 求将钩码挂到钩子上使天平平衡的方法的总数.其中可以把天枰看做一个以x轴0点作为平衡点的横轴 分析:力臂=重量 *臂长 = g[i]*c[j] 当平衡度k=0时,说明天枰达到平衡,k>0,说明天枰倾向右边(x轴右半轴),k<0则左倾 因此可以定义一个 状态数组dp[i][k],意为在挂满前i个钩码时,平衡度为k的挂法的数量. 由于距离c[i]的范围是-15~15,钩码重量的范围是1~25,钩码数量

POJ 3093 Margaritas on the River Walk (0-1背包变形)

这题目的思路很巧妙,什么情况下剩下的所有物品都放不下呢?就是当前剩余物品中最小的那个也放不下.所以,先把物品按照容量从小到大排序,依次枚举当前背包为放不下的最小物品的情况. 对于当前物品i,必有1到i-1的所有物品都放进去,这时候比i大的物品谁放谁不放是不确定的.转换成0-1背包问题:把前i-1个物品都放进去以后,得到空间为tsum - sum[i-1](前缀和)的包,只要从第i+1到第n个物品中拿出一个方案填充这个包使得剩余体积小于第i个物品的体积就可以了,把总方案数累加就是结果! 注意特殊情

POJ 3132 Sum of Different Primes DP背包

http://poj.org/problem?id=3132 题意: 给定n和k,问用恰好k个不同的质数来表示n的方案数. 分析: n和k都很小.反正就是个背包,选k个物品恰好填满n即可. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 bool dp[1200][15]; 6 int ct[1200][15]; 7 int p[1200]; 8 bool a[1200]; 9 int n, k,

Poj 1112 Rebuilding Roads(树形DP+背包)

题意:给你由N个点构成一颗树,问要孤立出一个有P个节点的子树最少需要删除多少条边.N的范围最大为150 N的范围不大,很容易想到在树上面做背包.把每个节点都看成一个背包,然后把每个儿子节点都看成是一组物品.为什么是一组呢,那是因为假设以儿子为根的节点的子树有S个节点,那么就有S+1种情况,要么将这整棵子树舍弃,要么从这个子树中取1-S个节点. 设f[i][j]为以i为根节点的子树,孤立出以i为根节点,一共含有j个节点的子树最少需要删除的边数(不包括删除i和他父亲的连接的那条边(假设i不是根节点)

HDU 2955 Robberies --01背包变形

这题有些巧妙,看了别人的题解才知道做的. 因为按常规思路的话,背包容量为浮点数,,不好存储,且不能直接相加,所以换一种思路,将背包容量与价值互换,即令各银行总值为背包容量,逃跑概率(1-P)为价值,即转化为01背包问题. 此时dp[v]表示抢劫到v块钱成功逃跑的概率,概率相乘. 最后从大到小枚举v,找出概率大于逃跑概率的最大v值,即为最大抢劫的金额. 代码: #include <iostream> #include <cstdio> #include <cstring>

POJ 1837 Balance

题意:给你C个挂钩,W个钩码,要你能使一个天平平衡 数据解释: 2 4 -2 3 3 4 5 8 以原点为支点,那么-2代表支点左边2处有一个钩码,同理3代表右边的点 所以案例数据有一个成立的例子是(3+5)*3=(4+8)*2或是(3+4+5)*2=8*3(力臂平衡) 有2种情况所以输出2: 思路:这个如果不是按照题目的分类说是DP我还想不到这个思路,我感觉我进步挺大了,能独立推出转移方程了. 首先我们看这道题首先是要求力平衡,那么一个限制是重量.与力相关的有钩码与挂钩的位置.显然,钩码可以放

codeforce Gym 101102A Coins (01背包变形)

01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXW 15005 #define N 155 #define LL long long #define MOD 1000000007 int w1[N],w2[N]; LL dp1[MAXW],dp2[MAXW]; int main(

hdu 4381(背包变形)

题意: 给定n个块,编号从1到n,以及m个操作,初始时n个块是白色. 操作有2种形式: 1 ai xi : 从[1,ai]选xi个块,将这些块涂白. 2 ai xi:从[ai,n]选xi个块,将这些块涂白. 可以忽略某些操作且如果区间内没有足够的黑块(黑块用于涂白),则不能进行这个操作. 分析: 写写画画一看就知道这道题是一个背包问题. “恰好装满背包”. 以下摘自题解: 本题难点在于正确处理两种操作,不妨假设只有一种操作,那么这种操作如果是1的话那么就把操作按照a从小到大排序,每次都尽量往最左