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,其实这一点结合上面博客里面的那
张表更好理解。也就是上面的格依靠的是下面相邻的两个格的值,那么更新只能从最大开始。因为如果从最小开始。那么
依靠的就是左边和下边的两个格了。这肯定不行。而完全背包恰好是这种情况,就是因为它确实是需要依靠左边和下面。
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;
}