一:题目
二:错误代码分析(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的数组太大。