题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543
题目大意:给一根长度为l的木棒,在木棒上放小棍子,每一根小棍子都有自己的长度和价值,要求保证小棍子的中心一定在木棒上(即可以伸出木棒一半的长度),最后求小棍子的最大价值和。
解题思路:01背包。但不同的是要考虑有几根小棍子悬在木棒的边上,有三种情况:0根、1根、2根,为了防止除以2之后出现小数,将所有的长度都乘上2,利用二维数组dp[i][j]表示当长度为i并且有j根小棍子悬在外面的情况下的总价值。
另外关于这道题目,个人感觉有一位大神的讲解很棒,把地址附上:http://blog.youkuaiyun.com/snowy_smile/article/details/49585417
AC代码:
#include <iostream>
#include <string.h>
using namespace std;
typedef long long LL;
int main()
{
int T;
int n,l;
LL max;
LL len[1005],value[1005];
LL dp[4005][5];
while(cin>>T)
{
for(int c=1;c<=T;c++)
{
max=0;
memset(dp,0,sizeof(dp));
cin>>n>>l;
l*=2;
for(int j=0;j<n;j++)
{
cin>>len[j]>>value[j];
len[j]*=2;
max = value[j]>max?value[j]:max;
}
for(int i=0;i<n;i++)
{
for(int j=l;j>=len[i]/2;j--)
{
for(int k=0;k<=2;k++)
{
if(j>=len[i])
dp[j][k] = (dp[j-len[i]][k]+value[i])>dp[j][k]?dp[j-len[i]][k]+value[i]:dp[j][k];
if(k>0)
dp[j][k] = dp[j-len[i]/2][k-1]+value[i]>dp[j][k]?dp[j-len[i]/2][k-1]+value[i]:dp[j][k];
if(max<dp[j][k])max = dp[j][k];
}
}
}
cout<<"Case #"<<c<<": "<<max<<endl;
}
}
return 0;
}
之前由于粗心,把for循环中的下标和其他变量搞混了,一直出不来正确答案………………一定要细心啊。
本文解析了HDU 5543题目的解题思路,采用01背包算法解决木棒放置小棍子的问题,并考虑了小棍子悬挂在木棒边上的特殊情况。通过调整长度单位和使用二维DP数组来实现最优价值求解。
283

被折叠的 条评论
为什么被折叠?



