andre_joy

导航

hdu 3535

地址:http://acm.hdu.edu.cn/showproblem.php?pid=3535

题意:混乱背包,s=0,至少选一种,s=1,最多选一种,s=2,随意选。

mark:分别三种情况背包。初始化的时候不能直接把dp[i-1][j]赋值给dp[i][j],必须取最大值。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int N = 110;
int n,t,m,s;
int v[N],w[N];
int dp[N][N];
int i,f;

int max(int a, int b) {return a > b ? a : b;}

void solve1()
{
    for(int k = 1; k <= m; k++)
        for(int j = t; j >= v[k]; j--)
        {
            if(dp[i][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
            if(dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]);
        }
}

void solve2()
{
    for(int j = t; j >= 0; j--)
    {
        dp[i][j] = max(dp[i][j], dp[i-1][j]);
        for(int k = 1; k <= m; k++)
            if(j >= v[k] && dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]);
    }
}

void solve3()
{
    for(int k = 1; k <= m; k++)
        for(int j = t; j >= 0; j--)
        {
            dp[i][j] = max(dp[i-1][j], dp[i][j]);  //找了好长时间的错!!!
            if(j >= v[k] && dp[i][j-v[k]] != -1)
                dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
            if(j >= v[k] && dp[i-1][j-v[k]] != -1)
                dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]);
        }
}

int main()
{
    int j,k;
    while(~scanf("%d%d", &n, &t))
    {
        memset(dp, -1, sizeof(dp));
        dp[0][0] = 0;
        f = 0;
        for(i = 1; i <= n; i++)
        {
            scanf("%d%d", &m, &s);
            for(j = 1; j <= m; j++)
                scanf("%d%d", v+j, w+j);
            if(f) continue;
            if(s == 0) solve1();
            else if(s == 1) solve2();
            else solve3();
            for(j = 0; j <= t; j++)
                if(dp[i][j] != -1) break;
            if(j == t+1) f = 1;
        }
        int ans = -1;
        for(i = 0; i <= t; i++)
            ans = max(ans, dp[n][i]);
        printf("%d\n", ans);
    }
    return 0;
}

posted on 2012-10-02 01:37  andre_joy  阅读(151)  评论(0编辑  收藏  举报