1 条题解

  • 0
    @ 2025-10-8 16:48:37

    【参考程序】

    01背包问题:如题,01指的是每个物品有选(1状态)和不选(0状态)两种状态,最后得到f数组。
    数据结构: bool f[]:f[i]等于True表示有办法选若干个物品使其总重量为i(即:i可以被填满) 算法分析与过程: 1、矛盾:不知道怎么选物品,也不知道选多少个。01背包算法很好解决这两个问题。 2、算法过程: (1)、物品逐个填f数组(让f数组的某些格子变成True),而且从大往小填 for(int j=v;j>=a[i];j--) (2)、对于某个j,此时的f[j]是没有a[i]的影响的,如果 f[ j-a[i] ]==1,那么f[j]就可以填(等于1) 有的同学会疑问:例如样例,有6 9 9 12 12 15 20。一开始,6先来填,它只让f[6]等于1,6表示不服气:它觉得它自己还能填更多的f,比如6+15可以让f[21]等于1。 我们可以安慰6:以后轮到15来填,15看到f[6]等于1,它就能让f[21]等于1。

    #include <bits/stdc++.h>
    using namespace std;
    int a[30];
    bool f[20001];
    int main()
    {
        int v, n; scanf("%d%d", &v, &n);
        for(int i=1; i<=n; i++) scanf("%d", &a[i]); 
        memset(f, 0, sizeof(f)); f[0] = 1;
        for(int i=1; i<=n; i++)
        {
            for(int j=v; j>=a[i]; j--)
            {
                if(f[j - a[i]] == 1) 
                {
                    f[j] = 1;
                }
            }
        }
        int p;
        for(int i=v; i>=0; i--) // 从大到小找到第一个为True的f值
        {
            if(f[i] == 1)
            {
                p = i;
                break;
            }
        }
        printf("%d\n", v - p);
        return 0;
    }
    
    • 1

    E08_2*【背包:填满型01背包】[NOIP 2001 普及组] 装箱问题

    信息

    ID
    96
    时间
    1000ms
    内存
    128MiB
    难度
    7
    标签
    递交数
    605
    已通过
    121
    上传者