简单01背包

问题描述

The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V,
(N <= 1000 , V <= 1000 )
representing the number of bones and the volume of his bag.
And the second line contain N integers representing the value of each bone.
The third line contain N integers representing the volume of each bone.

Output
One integer per line representing the maximum of the total value (this number will be less than 231).

Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1

Sample Output
14

源码

#include<iostream>
#include<stdio.h>
#include<string.h>
#define max(a, b) a > b ? a : b
using namespace std;
int dp[1005][1005];
// 物品数量 背包容量
// 物品价值
// 物品体积
int fun(int N, int W, int w[1000], int v[1000]) {
    int i, j;
    memset(dp, 0, sizeof(dp));

    for (j = 0; j <= W; j++) dp[0][j] = 0;
    //按以下方案填充数组,是一行一行的填充, 每一行填充完毕,才填充接下来的一行
    //翻译: 分别解决 前 1 个物品在, 0 ~ w下所能构成的最优装载方案
    //      前 2 个物品在 0 ~  w下最优填充方案
    //      但是可以理解为, 仅仅是对第二个物品的讨论, 只有放入与不放入, 并且分别讨论 容量为 0 ~ w 下个情况
    //      总结一句话, 分别讨论在 0 ~ w 总共 w 种情况下,第 2 个物品是否放入

    //      接下来讨论第 3 个 物品是否放入, 
    /*      要明白某一组确定的 i, j下 ,  dp[i][j] 的意思为, 前i个物品放入容量为j的背包的最大价值, 要始终名明确,
            i,j 的值不能改变, 相当于一个子问题*/
    //      自然地,若第三个物瓶确定不放入, 则  dp[i][j]    =    dp[i - 1][j]   注意j 的值不变‘
    //      若第三确定放入                则  dp[i][j]    =    dp[i - 1][j - w[i]] + v[i]
    //                                     ↑ 欲求原问题       ↑依赖于子问题
    for (i = 1; i <= N; i++)
    {
        for (j = 0; j <= W; j++)
        {
            if (j < w[i]) dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
        }
    }

    return dp[N][W];
}

int main() {
    int t;
    int N, W;

    cin >> t;
    while (t--) {
        int w[1000] = { 0 }, v[1000] = { 0 };
        int i;
        cin >> N;
        cin >> W;

        for (i = 1; i <= N; i++)
            cin >> v[i];

        for (i = 1; i <= N; i++)
            cin >> w[i];

       cout << fun(N, W, w, v) << endl;

    }
    //  system("pause");
    return 0;
}

一些感悟

大数组要开在全局区 数组的大小要严格按照题目的说明 对于多组数据的测试,每柱开始测试前所有数据都要初始化,很重要,有时候很可能单组数据可以过,多组就不行 对于循环的计数的起点要有一定的选择




本博客所有内容采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
转载文章请注明:简单01背包 - https://cser.blog/blog/easy-01-bag-question.html