动态规划(一)

一、背包问题

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;
}
相关推荐
s09071361 分钟前
FPGA加速:Harris角点检测全解析
图像处理·算法·fpga开发·角点检测
前端程序猿之路1 分钟前
30天大模型学习之Day 2:Prompt 工程基础系统
大数据·人工智能·学习·算法·语言模型·prompt·ai编程
星火开发设计18 分钟前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
2501_9418036225 分钟前
在柏林智能城市照明场景中构建实时调控与高并发能耗数据分析平台的工程设计实践经验分享
算法
福楠30 分钟前
C++ STL | list
c语言·开发语言·数据结构·c++·算法·list
努力学算法的蒟蒻30 分钟前
day55(1.6)——leetcode面试经典150
算法·leetcode·面试
s砚山s30 分钟前
代码随想录刷题——二叉树篇(十)
算法
2301_7644413332 分钟前
基于HVNS算法和分类装载策略的仓储系统仿真平台
人工智能·算法·分类
AI科技星36 分钟前
统一场论变化的引力场产生电磁场推导与物理诠释
服务器·人工智能·科技·线性代数·算法·重构·生活
杰克逊的日记38 分钟前
规控算法(规划 + 控制算法)
大数据·算法·云计算·it