就只加了一个if,时间翻了一倍,这应该怎么优化?

P1725 琪露诺

Februrary @ 2024-03-21 00:25:23

这是正确的代码,只有Subtask #1 的#11和#12超时。这两个点的答案也是正确的

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int N, L, R;
const int maxn = 200005;
LL ninf = -1e18; 
LL A[maxn];
LL dp[maxn];
LL ans = -1e10;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> N >> L >> R;
    for(int i = 0; i <= N; i++) cin >> A[i];

    // 初始化
    dp[0] = A[0];
    for(int i = 1; i <= N; i++) {
        int s = 0;
        int k = 0;
        for(int j = (i - R >= 0? i - R : 0); j <= i - L; j++) {
            if(dp[j] == ninf) continue;
            s = 1;
            if(k == 1) dp[i] = max(dp[i], dp[j]);
            else dp[i] = dp[j];
            k = 1;
        }
        dp[i] += A[i];
        if(s == 0) dp[i] = ninf;
    }

    for(int i = (N - R + 1 >= 0? N - R + 1 : 0); i <= N; i++) {
        ans = max(ans, dp[i]);
    }

    cout << ans << endl;

    return 0;
}

这是错误的代码,无法通过Subtask #2的两个测试点,但是可以通过Subtask #1的全部测试点

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int N, L, R;
const int maxn = 200005;
LL ninf = -1e18; 
LL A[maxn];
LL dp[maxn];
LL ans = -1e10;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> N >> L >> R;
    for(int i = 0; i <= N; i++) cin >> A[i];

    // 初始化
    dp[0] = A[0];
    for(int i = 1; i <= N; i++) {
        int s = 0;
        int k = 0;
        for(int j = (i - R >= 0? i - R : 0); j <= i - L; j++) {
            s = 1;
            dp[i] = max(dp[i], dp[j]);
            k = 1;
        }
        if(s == 0) dp[i] = ninf;
        dp[i] += A[i];
    }

    for(int i = (N - R + 1>= 0? N - R + 1: 0); i <= N; i++) {
        ans = max(ans, dp[i]);
    }

    cout << ans << endl;

    return 0;
}

两份代码的区别只是1个if判断,但是时间翻了几乎一倍?会这么夸张吗?有什么基于第一份代码的优化思路吗?


by MinLand @ 2024-09-08 13:56:31

这个题有一部分点,是走不到的,比如说我来一个L=10,R=11,N=12,我们发现0~9的部分,琪露诺走不到,其中的if(dp[j] == ninf) continue;可以看作判断了这个点是否可以走。

同样是这个问题,会导致不能通过HACK数据。


|