单调队列 poj1821 Fence

传送门:点击打开链接

题意:有K个工人,和长为N的篱笆,现在要给篱笆上色。每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱

问如何分配,使得K个工人的总利润最大

思路:先设出方程,设

dp[i][j]表示前i个工人,前j个篱笆的最大获利

那么就有

dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

dp[i][j]=max(dp[i][j],dp[i-1][k]+(j-k)*P[i]); j>=S[i],k<S[i]且k+L[i]>=j

那么我们就能想到用单调队列来优化了

这里主要要想清楚k的范围,那么就好做了

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;

const int MK = 1e2 + 5;
const int MX = 2e4 + 5;
const int INF = 0x3f3f3f3f;

int N, K, r, c, dp[MK][MX];
struct Team {
    int L, P, S;
    bool operator<(const Team &C) const {
        return S < C.S;
    }
} A[MK];
struct Data {
    int id, x;
    Data() { }
    Data(int _id, int _x) {
        id = _id; x = _x;
    }
} Q[MX];

int solve() {
    memset(dp, 0, sizeof(dp));
    for(int i = 1; i <= K; i++) {
        r = c = 0;
        Q[r++] = Data(0, 0);
        for(int j = 1; j <= N; j++) {
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            if(j >= A[i].S) {
                while(c < r && Q[c].id + A[i].L < j) c++;
                if(c < r) {
                    int Max = Q[c].x;
                    dp[i][j] = max(dp[i][j], Max + j * A[i].P);
                }
            }
            if(j < A[i].S) {
                Data temp(j, dp[i - 1][j] - j * A[i].P);
                while(c < r && Q[r - 1].x < temp.x) r--;
                Q[r++] = temp;
            }
        }
    }
    return dp[K][N];
}

int main() {
    //FIN;
    while(~scanf("%d%d", &N, &K)) {
        for(int i = 1; i <= K; i++) {
            scanf("%d%d%d", &A[i].L, &A[i].P, &A[i].S);
        }
        sort(A + 1, A + 1 + K);
        printf("%d\n", solve());
    }
    return 0;
}


你可能感兴趣的:(单调队列 poj1821 Fence)