集美大学_简单背包_60%通过segmentatio fault错误分析

一:题目

二:错误代码分析(60%通过并且段错误segmentation fault)

1:错误代码:

#include <stdio.h>

#include <iostream>
#include <string>
#include <algorithm>
#define ll long long int  //注意没有分号
using namespace std;

void process(int n,ll** arrbao,ll capacity,ll ** dp){

  
  ll i;
  for(i=0;i<n;i++){
    dp[i]=(ll*)malloc(sizeof(ll)*(capacity+1));

  }
  dp[0][1]=5;
    //j的类型错误 应该为ll
    ll j;
    for(i=0;i<n;i++){
        for(j=0;j<=capacity;j++){
            dp[i][j]=0;
        }
    }



    //这里的&&很重要
    for(j=0;j<arrbao[0][0]&&j<=capacity;j++){
        dp[0][j]=0;
    }
    for(j=arrbao[0][0];j<=capacity;j++){
        dp[0][j]=arrbao[0][1];
    }
  for(i=1;i<n;i++){
   // dp[i][capacity]=max(dp[i-1][capacity],arrbao[i][1]+dp[i-1][capacity-arrbao[i][0]]);
    for(j=0;j<=capacity;j++){
        //容量判断很重要
        if(j>=arrbao[i][0]){
            //注意类型匹配  注意赋初始值   注意是j而不是capacity
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-arrbao[i][0]]+arrbao[i][1]);
            //dp[i][j]=max(1,2);

        }else{
            dp[i][j]=dp[i-1][j];
        }
        

    }
        
  }
  /*
  int end;
    if(n>=1){
          end=dp[n-1][capacity];
         //注意释放内存

    }
  for(i=0;i<n;i++){
    free (dp[i]);
  }
  free(dp);
  return end;
  */

   
    

}

int main(){
    int n;

    cin >> n;
    ll ** arrbao=(ll **)malloc(sizeof(ll*)*n);

    int i;
    for(i=0;i<n;i++){
        arrbao[i]=(ll*)malloc(sizeof(ll)*2);
        cin >> arrbao[i][0];
        cin >> arrbao[i][1];
    }
    
    int q;
    //这句不能漏掉啊
    cin >> q;

    ll* ques=(ll*)malloc(sizeof(ll)*q);
    for(i=0;i<q;i++){
        cin >> ques[i];
    }


   ll maxques=0;
   for(i=0;i<q;i++){
    if(maxques<ques[i]){
        maxques=ques[i];
    }
   }

    ll ** dp=(ll**)malloc(sizeof(ll*)*n);
    //cout << maxques;
    process(n,arrbao,maxques,dp);


    for(i=0;i<q;i++){
        cout << dp[n-1][ques[i]] << endl;
    }
    //注意返回
    
    return 0;

}
    
    

2:错误问题具体分析

这个题目我只有60%通过。

题目:

我的代码中的dp[i][w]是到达第i个物品时w容量所能达到的最大价值,而在分配内存时就需要有n(物品个数)*w+1(询问容量的最大值+1)。

题目中容量w的上限是1e11,而1e11的一维数组的内存大小为800 GB,严重超标。

核心错误代码:

#include <stdio.h>

#include <iostream>
#include <string>
#include <algorithm>
#define ll long long int  //注意没有分号
using namespace std;
int main(){
  
    int n=1;
    long long capacity=10000000000;
    ll ** dp=(ll**)malloc(sizeof(ll*)*n);
    ll i;
    for(i=0;i<n;i++){
    dp[i]=(ll*)malloc(sizeof(ll)*(capacity+1));

  }
  dp[0][0]=5;
  
      
    
}

假设n的值为1,容量的最大值为1e10,则数组需要的字节数为8*(1e10+1),约等于800GB,因此内存无法分配这么多,因此出现段错误,用常规的dp[i][w]是无法解决这道题目的,因为w的数组太大。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值