HDU3496 Watch the Movie 背包

题目大意:给你n张电影门票,但一次只可以买m张,并且你最多可以看L分钟,接下来是n场电影,每一场电影a分钟,b价值,要求恰好看m场电影所得到的最大价值,要是看不到m场电影,输出0。

三个限制:

  1. 选电影门票的范围;
  2. 总共观看的时间;
  3. 买的票数严格为m。

因此,将第一维滚动处理,第二三维初值负无穷(因为是严格为m),倒序递推,最后取DP[m]中的最大值即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX_OBJ = 110, MAX_V = 100010, MAX_CNT = MAX_OBJ;
//DP(obj, v, cnt)=max{DP(obj-1, v, cnt), DP(obj-1, v-objV[obj], cnt-1)+objW[obj]}
int DP(int totV, int totObj, int totCnt, int *objV, int *objW)
{
    static int DP[MAX_CNT][MAX_V];
    memset(DP, 0xcf, sizeof(DP));
    DP[0][0] = 0;
    for (int obj = 1; obj <= totObj; obj++)
        for (int cnt = totCnt; cnt >= 1; cnt--)
            for (int v = totV; v >= 1; v--)
                if (v >= objV[obj])
                    DP[cnt][v] = max(DP[cnt][v], DP[cnt - 1][v - objV[obj]] + objW[obj]);
    int ans = 0;
    for (int v = 1; v <= totV; v++)
        ans = max(ans, DP[totCnt][v]);
    return ans;
}

int main()
{
#ifdef _DEBUG
    freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
    static int objV[MAX_OBJ], objW[MAX_OBJ];
    int T, totObj, objLimit, totV;
    scanf("%d", &T);
    while (T--)
    {
        memset(objV, 0, sizeof(objV));
        memset(objW, 0, sizeof(objW));
        scanf("%d%d%d", &totObj, &objLimit, &totV);
        for (int i = 1; i <= totObj; i++)
            scanf("%d%d", i + objV, i + objW);
        printf("%d\n", DP(totV, totObj, objLimit, objV, objW));
    }
    return 0;
}
View Code

 

posted @ 2018-03-04 16:02  headboy2002  阅读(98)  评论(0编辑  收藏  举报