BZOJ_2021

    首先一个贪心的思路就是,如果需要大奶酪,那么一定把大的放在上面,而且是把高度最小的大奶酪放在最上面。因此我们可以现将奶酪排个序,把小奶酪放下面,大奶酪放上面,而且大奶酪较矮的放在最上面。

    接着考虑放奶酪的决策,如果不用大奶酪的话自然就是一个裸的背包问题,如果用大奶酪就会涉及到一个问题,就是最上面的奶酪是原高,其余的都是原高的4/5,这时可以多加一个bit表示现在奶酪是不是已经“封顶”了,在“封顶”之前高度都按4/5算,“封顶”时按原高算即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 110
#define MAXT 1010
int N, T, K, f[MAXT][2];
struct St
{
    int v, h;
    bool operator < (const St &t) const
    {
        if((h < K && t.h < K) || (h >= K && t.h >= K))
            return h > t.h;
        return h < K;
    }
}st[MAXN];
void init()
{
    for(int i = 0; i < N; i ++) scanf("%d%d", &st[i].v, &st[i].h);
    std::sort(st, st + N);
}
void solve()
{
    memset(f, 0, sizeof(f));
    int ans = 0;
    for(int i = 0; i < N && st[i].h < K; i ++)
        for(int j = st[i].h; j <= T; j ++)
            f[j][0] = std::max(f[j][0], f[j - st[i].h][0] + st[i].v);
    ans = std::max(ans, f[T][0]);
    for(int i = 0; i < N; i ++)
    {
        if(st[i].h >= K)
        {
            for(int j = st[i].h / 5 * 4; j <= T; j ++)
                f[j][0] = std::max(f[j][0], f[j - st[i].h / 5 * 4][0] + st[i].v);
            for(int j = st[i].h; j <= T; j ++)
                f[j][1] = std::max(f[j][1], f[j - st[i].h][0] + st[i].v);
        }
        else
        {
            for(int j = st[i].h / 5 * 4; j <= T; j ++)
                f[j][0] = std::max(f[j][0], f[j - st[i].h / 5 * 4][0] + st[i].v);
        }
    }
    ans = std::max(ans, f[T][1]);
    printf("%d\n", ans);
}
int main()
{
    while(scanf("%d%d%d", &N, &T, &K) == 3)
    {
        init();
        solve();    
    }
    return 0;    
}

 

 

posted on 2012-10-05 16:44  Staginner  阅读(313)  评论(0编辑  收藏  举报