当前位置: 首页 > 知识库问答 >
问题:

背包-节省时间和记忆

琴镜
2023-03-14

根据维基百科和我查阅过的其他来源,你需要矩阵m[n][W]n-物品数和w-背包的总容量。这个矩阵变得很大,有时太大了,无法在C程序中处理它。我知道动态编程是基于节省内存的时间,但是,有什么解决方案可以节省时间和内存吗?

// Input:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)
for j from 0 to W do
  m[0, j] := 0
end for 
for i from 1 to n do
  for j from 0 to W do
    if w[i] <= j then
      m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
    else
      m[i, j] := m[i-1, j]
    end if
  end for
end for
int32 -> 32 * 123456789 * 100 bits
one_bit -> 1 * 123456789 * 100 bits
    long int i, j;
    long int *m[2];
    m[0] = (long int *) malloc(sizeof(long int)*(W+1));
    m[1] = (long int *) malloc(sizeof(long int)*(W+1));
    for(i = 0; i <= W; i++){
        m[0][i] = 0;
    }

    int read = 0;
    int write = 1;
    int tmp;

    long int percent = (W+1)*(n)/100;
    long int counter = 0;

    for(i = 1; i <= n; i++){
        for(j = 0; j <= W; j++){
            if(w[i-1] <= j){
                m[write][j] = max(m[read][j],(v[i-1]) + m[read][j-(w[i-1])]);
            }else{
                m[write][j] = m[read][j];
            }
            counter++;
            if(counter == percent){
                printf(".");    //printing dot (.) for each percent
                fflush(stdout);
                counter = 0;
            }
        }
        tmp = read;
        read = write;
        write = tmp;
    }

    printf("\n%ld\n", m[read][W]);

    free(m[0]);
    free(m[1]);

共有1个答案

季森
2023-03-14

背包问题可以使用O(W)空间来解决。
迭代的每一步中,您只需要2行-数组的当前状态M[i]M[i+1]

current = 1
int m[2][W]
set NONE for all elements of m # that means we are not able to process this state
m[0][0] = 0 # this is our start point, initially empty knapsack

FOR i in [1..n] do
    next = 3 - current; /// just use 1 or 2 based on the current index
    for j in [0...W] do
       m[next][j] = m[current][j]
    FOR j in [w[i]..W] do
       if m[current][j - w[i]] is not NONE then  # process only reachable positions
           m[next][j] = max(m[next][j], m[current][j - w[i]] + v[i]);
    current = next; /// swap current state and the produced one


也可以只使用1个数组。下面是伪代码

FOR i in [1..n] do
    FOR j in [w[i]..W] do
       m[j] = max(m[j], m[j - w[i]] + v[i]);
 类似资料:
  • 问题内容: 我有以下查询: 我有以下准备好的声明 如果我检查数据库,我发现它只插入今天的日期而不是时间,因此它将是: 我还应该投入些什么来打发时间? 问题答案: 您应该使用 Timestamp 和 setTimestamp* 方法来代替 Date 。 **** * 实际上,您必须执行以下操作: ....

  • 在讲座中,我们已经考虑了背包问题:有n个项的正权值为w1,..、wn和值v1,..vn和容量为W的背包。问题的可行解是使总重量不超过W的物品的子集。目标是找到一个最大可能总价值的可行解。对于权值均为正整数的情形,我们讨论了求解时间为O(nW)的背包问题的动态规划解法。 a)假设所有项目的权值都是正整数,而不是权值。项目的权值可以是任意的正实数。描述一个解决背包问题的动态规划算法,如果所有项目的值都

  • 问题内容: 我目前正在解析时间字符串并将其保存到数据库(Postgresql): 这给了我这个错误: 的类型是。 我也尝试将postgresql的类型设置为string并使用time数据类型: 但是现在在获取数据库中的记录时出现错误: 问题答案: 对此问题进行了进一步调查。当前,GORM中不支持任何日期/时间类型,除了 请参阅Dialect_postgres.go的这部分代码: 因此,基本上我可以

  • 我正在处理C++代码,其中我试图将保存在列表中,以便以后读取值并计算持续时间。 之所以在列表中保存时间,是因为我有多个对象,需要捕获该对象被检测到的当前时间,然后当该对象消失时,我必须计算该对象的持续时间。 错误(活动)E0304重载函数“std::list<_ty,_alloc>::insert[with_ty=double,_alloc=std::allocator]”的实例与参数列表不匹配

  • 具有特定组id的使用者连接到代理,监听主题不到1分钟,然后断开连接(根据业务逻辑)。当它监听主题时,它可以使用一些消息。当同一个使用者重复这个动作时,它会使用相同的消息! 我发现Kafka用间隔1分钟保存偏移。这意味着消费者必须听超过1分钟的主题。我怎样才能缩短这个间隔? 我发现了这样的属性: null null

  • 问题 你面前摆放着 n 个珠宝(共 n 种,每种 1 个),已知珠宝 s_i 的价值是 v_i ,重量是 w_i 。给你一个背包,你可以自由挑选珠宝装到背包中,但背包可以装载的最大重量为 t 。求背包能够装载珠宝的最大价值 v 。 解法 设 f(i,j) 为背包中放入前 i 件物品,重量不大于 j 的最大价值,其中 i in [1,n] , j in [0,t] 。有如下状态转移方程: f(i,j