Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) D - Travel Card

D - Travel Card

思路:dp,类似于单调队列优化。

其实可以写的更简单。。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 1e5 + 7;
const int M = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int n, t[N], dp[N][3], mn[N], a[N];
int st1[N], st2[N], head1, head2, rear1, rear2;

int main() {
    memset(dp, inf, sizeof(dp));
    memset(mn, inf, sizeof(mn));
    mn[0] = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &t[i]);
    }

    dp[1][0] = 20;
    dp[1][1] = 50;
    dp[1][2] = 120;

    st1[rear1++] = 1;
    st2[rear2++] = 1;

    for(int i = 2; i <= n; i++) {
        for(int j = 0; j < 3; j++) mn[i - 1] = min(mn[i - 1], dp[i - 1][j]);
        dp[i][1] = mn[i - 1] + 50;
        dp[i][2] = mn[i - 1] + 120;
        dp[i][0] = mn[i - 1] + 20;
        while(head1 < rear1 && t[i] - t[st1[head1]] >= 90) head1++;
        while(head2 < rear2 && t[i] - t[st2[head2]] >= 1440) head2++;

        if(head1 < rear1) dp[i][0] = min(dp[i][0], dp[st1[head1]][1]);
        if(head2 < rear2) dp[i][0] = min(dp[i][0], dp[st2[head2]][2]);

        while(head1 < rear1 && dp[i][1] < dp[st1[rear1 - 1]][1]) rear1--;
        while(head2 < rear2 && dp[i][2] < dp[st2[rear2 - 1]][1]) rear2--;

        st1[rear1++] = i;
        st2[rear2++] = i;
    }

    for(int j = 0; j < 3; j++) {
        mn[n] = min(mn[n], dp[n][j]);
    }

    for(int i = 1; i <= n; i++) {
        printf("%d\n", mn[i] - mn[i - 1]);
    }
    return 0;
}
/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9221161.html