http://acm.hdu.edu.cn/showproblem.php?pid=5543

 

题意:现在有一根长度为m的木板和一些小木棒,这些小木棒要放在长木板上并且每一根小木板的重心要在长木板上,即两端的小木棒长度可以露出一半的长(小木棒不可以重叠),当然,也可以不露,问你在符合题意的情况下最大能取到小木棒的价值为多少?

提示:若只有一根小木棒的话,需要预处理,因为只有一根木棒不管怎样它都可以保持平衡。

分析:一开始想着用一个变量去标记已经有几根木棒露出一半长,后来发现行不通,还是用数组标记方便点。。

 

 

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <math.h>

using namespace std;

#define INF 0x3f3f3f3f
const int maxn = 4100;
typedef long long LL;
int len[maxn];
long long value[maxn], dp[maxn][5];

int main()
{
    int T, n, m, t=1;

    scanf("%d", &T);

    while(T --)
    {
        scanf("%d %d", &n, &m);

        m *= 2;
        long long ans = 0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d %lld", &len[i], &value[i]);
            len[i] *= 2;
            ans = max(ans, value[i]);
        }

        memset(dp, 0, sizeof(dp));

        for(int i=1; i<=n; i++)
        {
            for(int j=m; j>=len[i]/2; j--)
            {
                for(int k=0; k<3; k++)
                {
                    if(j>=len[i])
                    dp[j][k]=max(dp[j][k], dp[j-len[i]][k]+value[i]);
                    if(k>0)
                    dp[j][k]=max(dp[j][k], dp[j-len[i]/2][k-1]+value[i]);

                    ans = max(ans, dp[j][k]);
                }
            }
        }

        printf("Case #%d: %lld\n", t++, ans);
    }
    return 0;
}
View Code

 

posted on 2016-08-18 10:26  不忧尘世不忧心  阅读(187)  评论(0编辑  收藏  举报