【做题笔记】P2871 [USACO07DEC]手链Charm Brace…

2020-02-14 16:03:02来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

【做题笔记】P2871 [USACO07DEC]手链Charm Bracelet

就是 01 背包。大意:给您 \(T\) 个空间大小的限制,有 \(M\) 个物品,第 \(i\) 件物品的重量为 \(c_i\) ,价值为 \(w_i\) 。要求挑选一些物品,使得总空间不超过 \(T\) ,且总价值最大。

考虑设 \(f_{i,j}\)\(1\) ~ \(i\) 件物品,背包容量为 \(j\) 时的最大价值,那么假如不选第 \(i\) 件物品,则为 \(f_{i-1,j}\) 的子问题(背包内只有 \(i-1\) 个物品);若选,则为 \(f_{i-1,j-w_i}+v_i\) 的子问题。

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int f[1001][1001],T,M,w[100001],v[100001];

int main()
{
    cin>>T>>M;
    for(int i=1;i<=M;i++)cin>>w[i]>>v[i];
    for(int i=1;i<=M;i++)
        for(int j=0;j<=T;j++)
            if(j<w[i])f[i][j]=f[i-1][j];
            else f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
    cout<<f[M][T]<<endl;
    return 0;
}

注意到这种做法本题会被卡。可以优化成一维,但过程很难想。

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

int f[1000001],T,M,w[1000001],v[1000001];

int main()
{
    cin>>M>>T;
    for(int i=1;i<=M;i++)cin>>w[i]>>v[i];
    for(int i=1;i<=M;i++)
        for(int j=T;j>=w[i];--j)
            f[j]=max(f[j],f[j-w[i]]+v[i]);
    cout<<f[T]<<endl;
    return 0;
}

原文链接:https://www.cnblogs.com/Nicest1919/p/12308579.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:golang学习笔记(一):包,变量,函数

下一篇:【做题笔记】P1042 乒乓球