首页 > 其他分享 >2.15 背包学习

2.15 背包学习

时间:2023-02-15 22:14:52浏览次数:71  
标签:背包 int cin 学习 -- using 2.15 include

1021. 货币系统

思路

完全背包求方案数,与01背包类似

#include <iostream>

using namespace std;

int n, m;
const int N = 20, M = 3010;
long long f[M];

int main() {
    cin >> n >> m;
    f[0] = 1;
    for (int i = 1; i <= n; i ++) {
        int v;
        cin >> v;
        for (int j = v; j <= m; j ++) {
            f[j] += f[j - v];
        }
    }
    
    cout << f[m] << endl;
    return 0;
}

\[\]

532. 货币系统

思路

这题首先要理解题目意思
理解后可以得知,答案就是从a数组中选出的,将a数组排序后,观察每个数是否能被前面的数表示
若能被表示说明不选,不能则选
就可以转化成一个完全背包求方案数问题

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 110, M = 25010;
int f[M];
int a[N];

int main() {
    int T;
    cin >> T;
    while (T --) {
        int n, cnt = 0;
        cin >> n;
        for (int i = 1; i <= n; i ++) cin >> a[i];
        sort(a + 1, a + 1 + n);
        memset(f, 0, sizeof f);
        f[0] = 1;
        for (int i = 1; i <= n; i ++) {
            if (!f[a[i]]) cnt ++;
            for (int j = 1; j <= a[n]; j ++) {
                if (j >= a[i]) f[j] += f[j - a[i]];
            }
        }
        cout << cnt << endl;
    }
    
    return 0;
}

\[\]

7. 混合背包问题

思路

混合背包是由01背包,完全背包,多重背包组成的混合体,事实上这三种背包在集合的确定上是相通的
且当前物品的最大价值和上件物品是什么样的没有关系,故能直接计算
对于每种不同的物品,用各自的方法计算即可。
同时由于多重背包使用二进制优化方法时和01背包状态转移类似,可以合并

#include <iostream>

using namespace std;

const int N = 1010;
int f[N];
int n, m;

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        int v, w, s;
        cin >> v >> w >> s;
        if (!s) {
            for (int j = v; j <= m; j ++) {
                f[j] = max(f[j], f[j - v] + w);
            }
        }else {
            if (s == -1) s = 1;            //若当前为01背包,则只有一种
            //多重背包二进制优化模板
            for (int k = 1; k <= s; k *= 2) {
                for (int j = m; j >= k * v; j --) {
                    f[j] = max(f[j], f[j - k * v] + k * w);
                }
                s -= k;
            }
            if (s) {
                for (int j = m; j >= s * v; j --) {
                    f[j] = max(f[j], f[j - s * v] + s * w);
                }
            }
        }
    }
    
    cout << f[m] << endl;
    
    return 0;
}

\[\]

10. 有依赖的背包问题

思路

树形dp + 分组背包
将每个节点当做一个物品组。用dfs遍历到叶子结点,然后一层层向上的物品组中选择最优解

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int n, m;
const int N = 110;
int f[N][N];
int v[N], w[N];
int h[N], e[N], ne[N], idx;

void add(int a, int b) {
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

void dfs(int u) {
    for (int i = h[u]; ~i; i = ne[i]) {
        int son = e[i];
        dfs(son);
        
        for (int j = m - v[u]; j >= 0; j --) {    //按体积划分
            for (int k = 0; k <= j; k ++) {
                f[u][j] = max(f[u][j], f[u][j - k] + f[son][k]);
            }
        }
    }
    
    for (int i = m; i >= v[u]; i --) f[u][i] = f[u][i - v[u]] + w[u]; //添加该节点的价值
    for (int i = 0; i < v[u]; i ++) f[u][i] = 0;
    //本节点中,不可能存在比该节点体积小的还有价值的方案,因为有依赖,该节点必须选择
}

int main() {
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    
    int root;
    for (int i = 1; i <= n; i ++) {
        int p;
        cin >> v[i] >> w[i] >> p;
        if (p == -1) {
            root = i;
        }else add(p, i);
    }
    
    dfs(root);
    
    cout << f[root][m] << endl;
    return 0;
}

\[\]

标签:背包,int,cin,学习,--,using,2.15,include
From: https://www.cnblogs.com/lbzbk/p/17124420.html

相关文章

  • 学习记录与心得(二)
    学习记录与心得作业课程https://edu.cnblogs.com/campus/fzzcxy/2023learning作业要求https://edu.cnbiogs.com/campus/fzzcxy/203learnig/homework/12898......
  • 《分布式技术原理与算法解析》学习笔记Day12
    调度框架:共享状态调度什么是共享状态调度?共享状态调度是为了解决单体调度和两层调度遇到的问题而创建出来的新的调度框架。它通过将单体调度器分解为多个调度器,每个调度......
  • xml基本学习
    概念:可拓展标记语言。可拓展即标签都是自定义的。标记语言即由标签构成的语言。功能:存储数据:配置文件在网络中传输语法基本语法:xml文件后缀名为.xmlxml第一行......
  • 数据结构刷题2023.02.15小记
    各排序算法时间复杂度如何提高哈希表的查找效率Hash表的查找效率取决于散列函数、处理冲突的方法和装填因子。显然,冲突的产生概率与装填因子(表中记录数与表长之比)的大小......
  • try...catch学习
    1.catch后面的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型2.catch可以写多个,可以精确处理异常,有利于程序的调试3.catch写多个的时候,必须遵循异常从上......
  • 学习TCP/IP(4):网际协议 IPv4-转发IP数据报
    学习TCP/IP(4):网际协议IPv4-转发IP数据报引言在网络的世界里,数据报转发可以分为两种类型:直接交付和间接交付。直接交付直接交付是指把数据报从一台机器通过物理网络......
  • 学习TCP/IP(1):分类的Internet地址
    学习TCP/IP(1):分类的Internet地址一个互联网主机可由名字(Names),地址(Address),路由(Route)来进行标识。Shoch是这样定义这三个术语的:Names,即名字,标识这个对象是什......
  • 学习TCPIP(2)-ARP协议
    学习TCPIP(2)-ARP协议ARP协议是这样一个协议:它负责将高层地址(IP地址)映射为底层物理地址(MAC地址)其中,IP地址是针对于TCPIP网络而言的,当目的地是网络A的主机H一个数据包抵......
  • 学习笔记分享:java面试(JDK、JRE、JVM的区别)
    简答题、问答题:1.JDK、JRE、JVM的区别:1)JDK:java开发工具包,是java的核心,包括:JRE+编译、运行等命令工具2)JRE:java运行环境,是运行java程序所必须的环境集合,包括:JVM+......
  • 2023.02.15.差分
    什么是差分首先有一个数组a,在里面包含数据我们定义一个数组b,使每个元素有一下规则b[i]=a[i]-a[i-1](a从一开始保存数据,a[0]=0)也就是说,a数组是b数组的前缀和数组,......