每日一题(10): poj1837

1. ac,1420K    32MS,

2. 这题是动态规划,这是网上的poj的提醒分类里面第一道动态规划。所以一般做这道题可能和我一样,之前还没懂

动态规划。其实动态规划目前我懂的就是把大问题分解为子问题来解决。

3. 这道题是需要用上全部的砝码的。一开始觉得这需要组合,那就太庞大了。但是觉得用动态也不对啊。因为需要

上全部的砝码。后来就明白了。网上大多数结题报告里面说的,dp[i][j] +=dp[i-1][j-s[k]*w[i]],并不是不用上全部砝码的

意思。而是说最终用上全部砝码的,只是依靠子问题来解决的。推荐一个博客:

http://blog.csdn.net/mu399/article/details/7722810

看懂其中的表格就可以明白了。不过要注意,这篇文字里的表格是从下倒上,从左到右,但是实际上,大多数情况下用

的是从左到右,从下到上。也就是里外层的循环不一样。当然,不影响结果。

4. 关于背包问题,再推荐一篇博客:

http://blog.csdn.net/kangroger/article/details/38864689

这篇可以列举完全背包和优化的问题。注意几点,首先是为什么空间优化,是从m到1,其实这一点结合上面博客里面的那

张表更好理解。也就是上面的格依靠的是下面相邻的两个格的值,那么更新只能从最大开始。因为如果从最小开始。那么

依靠的就是左边和下边的两个格了。这肯定不行。而完全背包恰好是这种情况,就是因为它确实是需要依靠左边和下面。

附上自己的代码,代码很简单的,关键是理解:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

//最大是20,所以开到25
const int maxs = 25;
int s[maxs];//臂长
int w[maxs];//砝码重量
int dp[maxs][12000];//动态规划数组,前i个砝码在平衡点j上有多少中平衡方法。
int c,g;
int main()
{
//freopen("input.txt","r", stdin);
//输入
cin>>c>>g;
for(int i = 1; i<=c; i++)
{
cin>>s[i];
}
for(int i = 1; i<=g; i++)
{
cin>>w[i];
}
//初始化
memset(dp,0,sizeof(dp));

dp[0][6000] = 1;
//动态规划
for(int i = 1; i<=g; i++)
{
for(int j = 1; j <= 12000; j++)
{
for(int k = 1; k <= c; k++ )
{
if(j>s[k]*w[i])
{
dp[i][j] += dp[i-1][j-s[k]*w[i]];
}

}
}
}

cout<<dp[g][6000]<<endl;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值