伙计们,我是竞争编程的新手,我正在解决一个问题(455A BOREDOM),我采取了一种解决方案并尝试使其理解。我相信我理解得很好,但是我有一个小疑问。
#include<bits/stdc++.h>
using namespace std;
#define MAX 100005
long long dp[100005];
long long count1[100005];
int main(){
int n,x;
cin>>n;
for(int i=0;i<n;i++){
cin >> x;
count1[x]++;
// res=max(res,x);
}
dp[0]=0;
dp[1]=count1[1];
for(int i=2;i<MAX;i++){
dp[i]=max(dp[i-1],dp[i-2]+i*count1[i]);
}
cout<<dp[MAX-1];
}
但是,您可以看到即使对于小型测试用例,循环也正在运行MAX(100005)。当我尝试进行优化时,我想到了以下解决方案:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long dp[100005];
long long count1[100005];
int n;
cin>>n;
int x;
int res=-100000;
for(int i=0;i<n;i++){
cin >> x;
count1[x]++;
res=max(res,x);
}
dp[0]=0;
dp[1]=count1[1];
for(int i=2;i<=res;i++){
dp[i]=max(dp[i-1],dp[i-2]+i*count1[i]);
}
cout<< dp[res];
}
但这给我关于测试用例12 https://codeforces.com/contest/455/submission/47841668
的错误答案该网站在测试案例12中报告了以下错误:
运行时错误:带符号的整数溢出:98997 * 8608623459288743937无法用'long long'类型表示
在此行dp[i]=max(dp[i-1],dp[i-2]+i*count1[i]);
谁能告诉我我在哪里做错了? 为什么那个有竞争力的程序员那样的错误是正常的?
答案 0 :(得分:1)
区别在于,现在您将long long count1[100005];
移到int main()
内,不再像默认值一样初始化为0
了。
Why are global and static variables initialized to their default values?
所以当您这样做
for(int i=0;i<n;i++){
cin >> x;
count1[x]++;
res=max(res,x);
}
count1 [x]具有随机的垃圾值,您可以对其进行递增,然后在以下位置进行计算:dp[i]=max(dp[i-1],dp[i-2]+i*count1[i])
导致站点报告运行时错误:
运行时错误:带符号的整数溢出:98997 * 8608623459288743937不能在此行上以'long long'类型表示dp [i] = max(dp [i-1],dp [i-2] + i * count1 [ i]);
您可以看到在这种情况下count1 [i]是8608623459288743937
要解决此问题,您可以将long long count1[100005];
替换为long long count1[100005]= {};
How to initialize all members of an array to the same value?
注意:dp
也不会自动初始化为0。但是,这不是问题,因为您不会像使用dp
那样读取count1
的未初始化值。 dp[i-1]
和dp[i-2]
在此处dp[i]=max(dp[i-1],dp[i-2]+i*count1[i]);