poj 1837 Balance (DP)

题目链接:http://poj.org/problem?id=1837

题意:给你一个天枰,再给你秤上一些挂钩的位置和秤砣,让你计算用这些钩子和秤砣使这个天枰平衡的方法数(秤砣必须全部使用)

题外话:这道是学长去年的Dp练习题,今天拿来做一下,刚开始的时候感觉这个题根本和Dp根本不占边呀(还是太弱了),之后去请教了一下隔壁寝室的大神,感觉豁然开朗。

思路:dp[i][j]表示用前i种秤砣,组成质量为j时的方法数,因为左边的挂钩是带重量的,而每个秤砣在天枰上产生的实际重量应该是 挂钩的位置*秤砣的质量 ,所以j就可能为负值,C++不支持带负数的数组,所以就把所有的权重+10000(大致计算了一下 这些秤砣产生的最大重量不可能超过一万),随意此时天秤的平衡状态就是j=10000的状态,最后输出dp[G][10000]。将dp数组初始化为零,将dp[0][10000]设成1(天枰本来就是平衡的)。    

Code:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define SIZE_M 25
#define SIZE_N 20005
#define INF 100000000

int dp[SIZE_M][SIZE_N];
int c[SIZE_M];
int g[SIZE_M];
int C,G;
int main()
{
    scanf("%d%d",&C,&G);
    for(int i=0;i<C;i++) scanf("%d",&c[i]);
    for(int i=1;i<=G;i++) scanf("%d",&g[i]);
    memset(dp,0,sizeof(dp));
    dp[0][10000]=1; 
    for(int i=1;i<=G;i++){
        for(int j=0;j<20000;j++){
            if(dp[i-1][j]){
                for(int k=0;k<C;k++) dp[i][j+g[i]*c[k]]+=dp[i-1][j];  
            }
        }
    }
    printf("%d\n",dp[G][10000]);
    return 0;
}


总结: 这道题其实是背包问题很相似,在这两个问题中i都表示使用前i种物品,j都表示使用前i种物品所产生的一种属性,dp数组都是用来存最终结果,更新过程都是根据i-1的

所有j的值来更新所有i的j值,这其实是一种思维的方式,深悟,理解,体会~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值