二维费用的背包问题

来源:互联网 发布:安装Linux出现内部错误 编辑:程序博客网 时间:2024/04/29 22:33

题目:toj3596

题意:有N张光盘,每张光盘有一个价钱,现在要从N张光盘中买M张,预算为L,每张光盘有一个快乐值,要求在不超过预算并且恰好买M张,使得快乐值最大。

解答:典型的二维费用背包问题,另外一种隐含的费用为个数,每个物品的个数费用为1。要求恰好买M张表示要求恰好装满,所以初始化不是0,而是-INF。

二维背包的状态转移方程:F[i, v, u] = max{F[i − 1, v, u], F[i − 1, v − Ci, u − Di] + Wi}

如果空间优化,u,v必须均逆序。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int MAXN = 1010;const int INF = 1 << 31;struct Movie{    int t,v;};Movie movie[MAXN];int dp[MAXN][MAXN];int n,m,l;int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&n,&m,&l);        for(int i = 1;i <= m;i++)            for(int j = 0;j <= l;j++)                dp[j][i] = -INF;        for(int j = 0;j <= l;j++)            dp[j][0] = 0;        for(int i = 1;i <= n;i++)            scanf("%d%d",&movie[i].t,&movie[i].v);        for(int i = 1;i <= n;i++)            for(int j = l;j >= movie[i].t;j--)            for(int k = m;k >= 1;k--)            dp[j][k] = max(dp[j][k],dp[j-movie[i].t][k-1]+movie[i].v);        int ans = 0;        for(int i = 1;i <= l;i++)            if(dp[i][m] > ans)            ans = dp[i][m];        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击