• 背包问题


    1. 01背包

    问题描述:

    小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次。为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值。现在他想知道,凭借他手上的这些奖券,可以换到哪些奖品,使得这些奖品的喜好值之和能够最大。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define M 100005
     4 int V[M];
     5 
     6 int main()
     7 {
     8     int n, m, need, value, i, j;
     9     scanf("%d%d", &n, &m);
    10     for (i = 0; i < n; i++)
    11     {
    12         scanf("%d%d", &need, &value);
    13         for (j = m; j >= need; j--)  //逆向
    14         {
    15             if (V[j - need] + value>V[j])
    16                 V[j] = V[j - need] + value;
    17         }
    18     }
    19     printf("%d
    ", V[m]);
    20     return 0;
    21 }

    2. 完全背包

    问题描述:

    小Ho现在手上有M张奖券,而奖品区有N种奖品,分别标号为1到N,其中第i种奖品需要need(i)张奖券进行兑换,并且可以兑换无数次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值。现在他想知道,凭借他手上的这些奖券,可以换到哪些奖品,使得这些奖品的喜好值之和能够最大。

    #include<stdio.h>
    #include<string.h>
    #define M 100005
    int V[M];
    
    int main()
    {
        int n, m, need, value, i, j;
        scanf("%d%d", &n, &m);
        for (i = 0; i < n; i++)
        {
            scanf("%d%d", &need, &value);
            for (j = need; j <=m; j++) //正向
            {
                if (V[j - need] + value>V[j])
                    V[j] = V[j - need] + value;
            }
        }
        printf("%d
    ", V[m]);
        return 0;
    }

    3. 多重背包

    http://blog.csdn.net/insistgogo/article/details/11176693

    有N种物品和一个容量为V的背包。第i种物品最多有num[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装

    入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 

    例:

    http://hihocoder.com/problemset/problem/1364

    可以转化为多重背包。用0-1背包做会超时。

    #include <iostream>
    #include <vector>
    #include <map>
    using namespace std;
    
    map<pair<int, int>, int> cnt;
    
    int main()
    {
        int n, m, w, p, num;
        cin >> n >> m;
        for (int i = 0; i < n; i++)
        {
            cin >> w >> p;
            cnt[make_pair(w, p)]++;
        }
        vector<pair<int, int>> v;
        for (map<pair<int, int>, int>::iterator it = cnt.begin(); it != cnt.end(); it++)
        {
            w = it->first.first;
            p = it->first.second;
            num = it->second;
            for (int k = 1; num; k <<= 1)
            {
                if (k <= num)
                {
                    v.push_back(make_pair(w*k, p*k));
                    num -= k;
                }
                else
                {
                    v.push_back(make_pair(w*num, p*num));
                    num = 0;
                }
            }
        }
        vector<int> pr(m + 1, 0);
        for (int l = v.size(), i = 0; i < l; i++)
        {
            w = v[i].first;
            p = v[i].second;
            for (int j = m; j >= w; j--)
                pr[j] = max(pr[j], pr[j - w] + p);
        }
        cout << pr[m] << endl;
    
        return 0;
    }
  • 相关阅读:
    TextWatcher 监视EditText的输入
    【Android】SqLitOpenHelper操作数据库
    【第一个开源项目】最完整的Andoird联系人操作,完美支持联系人的各种属性操作。
    Ext.ux.grid.RowEditor更新
    『转』如何判断Store加载完毕
    MyEclipse8.6安装svn插件
    『转』Eclipse中设置编码的方式
    『转』jsonlib json 格式 Date
    Spring Security的关键组件
    Ext.grid之numbercolumn格式化输出
  • 原文地址:https://www.cnblogs.com/argenbarbie/p/4835531.html
Copyright © 2020-2023  润新知