ACWING基础算法模板题 背包

1)01背包

        每个物品每次只能用一次。

二维数组版:


    const int N =  1010;
    int w[N], dp[N][N], v[N];
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i =1; i<= n; i++)
    {
        cin>>v[i]>>w[i];
    }
   for(int i=1;  i<=n; i++)
    {
        for (int j=1; j<=m; j++)
        {
            dp[i][j] = dp[i-1][j];
            if(v[i] <= j) dp[i][j] = max(dp[i][j], dp[i-1][j-v[i]] + w[i]);
        }
    }
    cout<<dp[n][m];

一维优化版:


    const int N =  1010;
    int w[N], dp[N], v[N];
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i =1; i<= n; i++)
    {
        cin>>v[i]>>w[i];
    }
   for(int i=1;  i<=n; i++)
    {
        for (int j=m; j>=v[i]; j--)
        {
            dp[j] = max(dp[j], dp[j-v[i]] + w[i]);
        }
    }
    cout<<dp[m];

2)完全背包

                每个物品能放无限多个;

优化版:

    const int N =  1010;
    int w[N], dp[N], v[N];
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i =1; i<= n; i++)
    {
        cin>>v[i]>>w[i];
    }
    for(int i = 1;  i<=n; i++)
    {
        for (int j= v[i] ; j<= m; j++)
        {
             dp[j] = max(dp[j], dp[j-v[i]] +w[i]);   
        }
    }
    cout<<dp[m];

3)多重背包

        每个物品能放有限个。

暴力01

 int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i<= n; i++)
    {
        scanf("%d%d%d", &v[i], &w[i], &s[i]);
    }
    for(int i = 1; i<= n; i++)
    {
        for(int j =0; j<= m; j++ )
        {
            for(int k = 0; k<= s[i]; k++)
            {
                if(k*v[i] <= j) dp[i][j] = max(dp[i][j], dp[i-1][j- k*v[i]] + k*w[i]);
            }
        }
    }
    cout<<dp[n][m];

暴力优化:

 int n, m;
    cin>>n>>m;
    for(int i =1; i<=n; i++)
    {
        int v, w,s;
        cin>>v>>w>>s;
        for(int k=1; k<=s; k++)
        {
            for(int j = m; j>=v; j--)
            {
                dp[j] = max(dp[j], dp[j-v] + w);
            }
        }
    }
    cout<<dp[m];

二进制优化:把数量[0, s]数组利用二进制转换为logn的二进制数组[1, 2, 4……k] k<=s, k%2 == 0,该数组能凑成0~s间所有的数。

int n, m;
    cin>>n>>m;
    vector< pair<int, int> > q;
    q.push_back(make_pair(0, 0 ));
    for(int i  =1; i<=n; i++)
    {
        int v, w, s;
        cin>>v>>w>>s;
        for(int k = 1; k<=s; k++)
        {
            s -= k;
            q.push_back(make_pair(k*v, k*w));
        }
        if(s) q.push_back(make_pair(s*v, s*w));
    }
    
    for(int i =1; i<= (int) q.size(); i++)
        for(int j=m; j>=q[i].first; j-- )
          dp[j] = max(dp[j], dp[j-q[i].first]+q[i].second);  
    cout<< dp[m];

4)分组背包

                每组物品只能选一个放入背包;

二维数组版:

    int n, m;
    cin>>n>>m;
    for(int i = 1; i<= n; i++)
    {
        cin>>s[i];
        for(int k = 1; k<= s[i]; k++)
            cin>>v[i][k]>>w[i][k];
    }
    for(int i = 1; i <= n; i++ )
    {
        for(int j = m; j >= 0; j--)
        {  
            dp[i][j] = dp[i-1][j];
            for(int k = 0; k <= s[i]; k++)
            {
                if(v[i][k] <= j) dp[i][j] = max(dp[i][j], dp[i-1][j-v[i][k]] + w[i][k]);
            }
        }
    }
    cout<<dp[n][m];

一维优化版:

int n, m;
    cin>>n>>m;
    
    for(int i = 1; i<= n; i++)
    {
        cin>>s[i];
        for(int k = 1; k<= s[i]; k++)
            cin>>v[i][k]>>w[i][k];
    }
    for(int i = 1; i <= n; i++ )
    {
        for(int j = m; j >= 0; j--)
        {  
            for(int k = 0; k <= s[i]; k++)
            {
                if(v[i][k] <= j) dp[j] = max(dp[j], dp[j-v[i][k]] + w[i][k]);
            }
        }
    }
    cout<<dp[m];

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值