Cpp环境【Code[VS]5226】物品选取

背包问题求解
本文介绍了一个包含甲乙丙三类物品的背包问题解决方案,通过动态规划的方法实现了对背包最大价值的计算,特别针对甲类物品的价值与体积之间的二次函数关系进行了详细解析。
【问题描述】      

  小沐同学确信所有问题都有个多项式时间算法,为了证明,他决定自己去当一次旅行商,在上路之前,小 X 需要挑选一些在路上使用的物品,但他只有一个 能装体积为 m 的背包。显然,背包问题对小沐来说过于简单了,所以他希望你来帮他解决这个问题。
  小沐可以选择的物品有 n样,一共分为甲乙丙三类:
  1.甲类物品的价值随着你分配给他的背包体积变化,它的价值与分配给它的体积满足函数关系式,v(x) = A*x^2-B*x,x表示分配给该物品的体积,为非负整数,A,B是每个甲类物品的两个参数。注意每个体积的甲类物品只有一个。
  2.乙类物品的价值 A和体积 B都是固定的,但是每个乙类物品都有个参数C,表示这个物品可供选择的个数。
  3.丙类物品的价值 A和体积 B也是固定的,但是每个丙类物品可供选择的个数都是无限多个。
  你最终的任务是确定小沐的背包最多能装有多大的价值上路。

【输入格式】  

  第一行两个整数 n,m,表示背包物品的个数和背包的体积;
  接下来 n行,每行描述一个物品的信息。第一个整数 x,表示物品的种类:
  若 x 为1表示甲类物品,接下来两个整数 A,B,为A类物品的两个参数;
  若 x 为2表示乙类物品,接下来三个整数 A,B,C。A表示物品的价值,B表示它的体积,C 表示它的个数;
  若 x 为3表示丙类物品,接下来两个整数A,B。A表示它的价值,B表示它的体积。

【输出格式】  

  仅一行为一个整数,表示小 X的背包能装的最大价值。

【输入样例】  

【样例1】
 1 0
 1 1 1

【样例2】
 4 10
 2 1 2 1
 1 1 2
 3 5 2
 2 200 2 3

【输出样例】  

【样例1】
 0

【样例2】
 610

【数据范围】  

对于50%的数据,只有乙和丙两类物品;
对于70%的数据,1<=n<=100, 1<=m<=500,0<=A,B,C<=200;
对于100%的数据,1<=n<=100, 1<=m<=2000,0<=A,B,C<=200;

【来源】

复赛模拟题
Code[VS]5226 原题传送矩阵
重庆一中题库 原题传送矩阵

【思路梳理】

  背包问题,互相伤害,乙丙显然是一样的思路很容易解决主要还是看甲类:枚举给甲类的第i样物品分配多少即可!!!
  可以证明的是:如果要选择某样甲类物品i,只要它的参数a[i].A是一个正数,那么显然选择其的体积越大,就越划算,换句话来说:这个物品一定。不严格证明如下:

当a[i].A是一个正数时,其价值与体积成二次函数关系:
    这里写图片描述
    定义域为该物品能够选取的体积,值域为其对应的价格

   根据初等数学知识可以知道,二次函数为凹函数,那么其选取的体积越大,价值也就越大是必然的,显然我们还可以根据图像知道斜率也随之增大,也就是说单位体积的价值在增大,那么选取x个单位体积的该物品一定比选取x-1个单位的该物品的结果更优。
这里写图片描述

可列出如下的状态函数&状态转移方程,时间复杂度这里写图片描述

d(i,j)=从前i样物品中任意选择总体积不超过j的物品所能够形成的最大价值

d[i][j]=
Case1: max{ d(i-1,j-x)+a[i].A*x*x-a[i].B*x | 0<=x<=j,x代表选择分配的体积 }
Case2:max{d(i-1,j-k*a[i].B)+a[i].A*k | 0<=k<=min(a[i].C,j/a[i].B)}
Case 3: max( d(i-1,j-k*a[i].B)+a[i].A*k | 0<=k<=j/a[i].B )

【Cpp代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 105
#define maxm 2005
using namespace std;
int n,m,d[maxm];
struct data
{
    int type,A,B,C;
}a[maxn];

void dp()
{
    //d(i,j)=从前i样物品中任意选择总体积不超过j的物品所能够形成的最大价值
    //          Case 1:  max{ d(i-1,j-x)+a[i].A*x*x-a[i].B*x | 0<=x<=j,x代表选择分配的体积  }
    //d(i,j)= { Case 2:  max{ d(i-1,j-k*a[i].B)+a[i].A*k     | 0<=k<=min(a[i].C,j/a[i].B)   }
    //          Case 3:  max( d(i-1,j-k*a[i].B)+a[i].A*k     | 0<=k<=j/a[i].B

    for(int i=1;i<=n;i++)
    {
        if(a[i].type==1)
        {
            for(int j=m;j>=0;j--)
            for(int x=j;x>=0;x--)
                d[j]=max(d[j],d[j-x]+a[i].A*x*x-a[i].B*x);
        }

        if(a[i].type==2)
        {
            for(int j=m;j>=0;j--)
            for(int k=a[i].C;k>=0;k--)if(j-k*a[i].B>=0)
                d[j]=max(d[j],d[j-k*a[i].B]+a[i].A*k);
        }

        if(a[i].type==3)
        {
            for(int j=a[i].B;j<=m;j++)
                d[j]=max(d[j],d[j-a[i].B]+a[i].A);
        }

    }

    cout<<d[m];
}

int main()
{
//  freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].type);
        if(a[i].type==1)        scanf("%d%d",&a[i].A,&a[i].B);
        else if(a[i].type==2)       
        scanf("%d%d%d",&a[i].A,&a[i].B,&a[i].C);
        else if(a[i].type==3)       
        {
            scanf("%d%d",&a[i].A,&a[i].B);
            a[i].C=2005;//物品的体积至少为1,背包最大容积为2000,所以可以认为2005为无限个 
        }
    }

    dp();   

    return 0;
}
### 关于 Visual Studio Code 配置 C++ 开发环境的超详细教程 以下是针对 Visual Studio Code (VS Code) 的 C++ 开发环境配置的详细介绍: #### 1. 安装必要的组件 要使 VS Code 支持 C++ 开发,需先安装以下必要组件: - **C++ 扩展包**: 在 VS Code 市场中搜索并安装 Microsoft 提供的 “C/C++” 扩展[^2]。 - **编译器**: 推荐使用 GCC 或 Clang 编译器。对于 Windows 用户,可以通过 MinGW-w64 下载 GCC;而对于 Linux 和 macOS,则通常自带或可通过包管理器轻松获取。 - **调试工具**: 可选 GDB、LLDB 或者 CDB 来支持调试功能。 #### 2. 创建工作区和源文件 创建一个新的文件夹作为项目的工作目录,并在其中添加一个简单的 `.cpp` 文件用于测试。例如 `main.cpp`: ```cpp #include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; } ``` #### 3. 配置 IntelliSense (`c_cpp_properties.json`) IntelliSense 是 VS Code 中非常重要的特性之一,它提供了智能感知和语法高亮等功能。为此需要手动设置 `c_cpp_properties.json` 文件来指定头文件路径和其他选项。 进入命令面板(Ctrl+Shift+P),输入并执行 `"C/Cpp: Edit Configurations"`,会自动生成如下结构的内容到 `.vscode/c_cpp_properties.json` 文件中: ```json { "configurations": [ { "name": "Win32", "includePath": ["${workspaceFolder}/**"], "defines": [], "compilerPath": "/path/to/compiler", // 替换为实际编译器路径 "cStandard": "c17", "cppStandard": "c++17" } ], "version": 4 } ``` 注意修改 `compilerPath` 字段指向本地已安装的编译器位置。 #### 4. 设置构建任务 (`tasks.json`) 为了让程序能够被成功编译运行,还需要定义好对应的构建任务。同样通过命令面板调用 `"Tasks: Configure Task"` 后,在弹出窗口里选择 `"Create tasks.json file from template"` 并选取 `"Others"` 类型模板即可生成基础框架代码片段至 `.vscode/tasks.json` 当前活动项目的根目录下: ```json { "version": "2.0.0", "tasks": [ { "label": "build hello world", "type": "shell", "command": "g++", "args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": ["$gcc"] } ] } ``` 上述脚本实现了利用 g++ 对当前打开的 cpp 源码进行单步编译操作的功能。 #### 5. 调试配置 (`launch.json`) 最后一步便是安排启动参数以及附加信息给定断点追踪使用的 launch configuration 。依旧借助 command palette 输入 `"Debug: Open Launch Configuration"` ,然后按照提示填写相关信息保存下来形成最终版本: ```json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "build hello world", "miDebuggerPath": "/usr/bin/gdb" // 修改为你自己的GDB路径 } ] } ``` 此部分指定了如何加载目标二进制可执行文件及其关联属性以便后续交互式分析过程得以顺利开展。 #### 6. 格式化代码风格 为了保持团队协作中的统一编码习惯,可以引入 clang-format 工具配合特定样式指南完成自动调整缩进等工作流环节。具体做法参照官方文档说明链接地址 [Clang Format Style Options](https://clang.llvm.org/docs/ClangFormatStyleOptions.html)[^3] 实现定制化的 .clang-format 文档存放在仓库顶层或者个人偏好设定区域之下生效范围覆盖整个解决方案内的所有子模块单元格内容一致表现形式达成共识标准水平线以上质量保障体系建立起来更加完善可靠持久耐用长期维护成本降低效率提升显著效果明显可见一斑。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值