杭电ACM5543(01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543
题目大意:给一根长度为l的木棒,在木棒上放小棍子,每一根小棍子都有自己的长度和价值,要求保证小棍子的中心一定在木棒上(即可以伸出木棒一半的长度),最后求小棍子的最大价值和。
解题思路:01背包。但不同的是要考虑有几根小棍子悬在木棒的边上,有三种情况:0根、1根、2根,为了防止除以2之后出现小数,将所有的长度都乘上2,利用二维数组dp[i][j]表示当长度为i并且有j根小棍子悬在外面的情况下的总价值。
另外关于这道题目,个人感觉有一位大神的讲解很棒,把地址附上:http://blog.csdn.net/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循环中的下标和其他变量搞混了,一直出不来正确答案………………一定要细心啊。

你可能感兴趣的:(ACM,杭电)