动态规划(一)

一、背包问题

1.1 01背包问题

**特点:**每件物品最多只用于一次

属性包括:最大值(Max)、最小值(Min)、数量

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n,m;
int v[N],w[N];
int f[N][N];

int main()
{
    cin>>n>>m;

    for(int i = 1;i <= n; i++) cin>>v[i]>>w[i];

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

    return 0;
}

1.2 完全背包问题

**特点:**每件物品有无限个

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n,m;
int v[N],w[N];
int f[N][N];

int mian()
{
    cin>>n>>m;
    for(int i = 1;i <= n;i ++) cin>>v[i]>>w[i];
    
    for(int i = 1;i <= n;i ++)
        for(int j = 0; j <= m;j ++)
            for(int k = 0;k * v[i] <= j; k ++)
                f[i][j] = max(f[i][j],f[i - 1][j - v[i] * k] + w[i] * k);
    
    cout<<f[n][m]<<endl;
    
    return 0;
}

1.3 多重背包问题

**特点:**每个物品的个数不同

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 25000,M = 2010;

int n,m;
int v[N],w[N];
int f[N];

int main()
{
    cin>>n>>m;
    int cnt = 0;
    for(int i = 1;i <= n;i ++)
    {
        int a,b,s;
        cin>>a>>b>>s;
        int k = 1;
        while(k <= s)
        {
            cnt ++;
            v[cnt] = a * k;
            w[cnt] = b * k;
            s -= k;
            k *= 2;
        }
        if(s > 0)
        {
            cnt ++;
            v[cnt] = a * s;
            w[cnt] = b * s;
        }
    }
    
    n = cnt;
    for(int i = 1;i <= n;i ++)
        for(int j = m;j >= v[i];j --)
           f[j] = max(f[j],f[j - v[i]] + w[i]);
    
    cout<<f[m]<<endl;
    
    return 0;
}

1.4分组背包问题

**特点:**物品有n组,每一组物品中有若干个

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 110;

int n,m;
int v[N][N],w[N][N],s[N];
int f[N];

int main()
{
    cin>>n>>m;

    for(int i = 1;i <= n;i ++)
    {
        cin>>s[i];
        for(int j = 0;j < s[i];j ++)
        {
            cin>>v[i][j]>>w[i][j];
        }
    }


    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)
                   f[j] = max(f[j],f[j - v[i][k]] + w[i][k]);

    cout<<f[m]<<endl;

    return 0;
}
相关推荐
mygugu1 分钟前
归纳理解epoch、batch、batch size、step、iteration深度学习名词
人工智能·算法
AI科技星11 分钟前
基于双隐含量(角速度 +质量 )的全量变形公式体系-发现新公式
开发语言·人工智能·线性代数·算法·矩阵·数据挖掘
minji...20 分钟前
Linux 基础IO (三) (用户缓冲区/内核缓冲区深刻理解)
java·linux·运维·服务器·c++·算法
困死,根本不会29 分钟前
蓝桥杯python备赛笔记之(八)动态规划(DP)
笔记·python·学习·算法·蓝桥杯·动态规划
whycthe37 分钟前
c++动态规划算法详解
c++·算法·动态规划
不想看见4041 小时前
Single Number位运算基础问题--力扣101算法题解笔记
数据结构·算法
靠沿1 小时前
【优选算法】专题十二——栈
算法
无心水1 小时前
【任务调度:框架】10、2026最新!分布式任务调度选型决策树:再也不纠结选哪个
人工智能·分布式·算法·决策树·机器学习·架构·2025博客之星
我头发还没掉光~1 小时前
【C++写详细总结①】从for循环到算法初步
数据结构·c++·算法
【数据删除】3482 小时前
计算机复试学习笔记 Day41
笔记·学习·算法