其他分享
首页 > 其他分享> > G - Most Dangerous Shark dp 单调栈 单调队列

G - Most Dangerous Shark dp 单调栈 单调队列

作者:互联网

 

题意:

一条线段上有n张骨牌(n=1e7), 相邻骨牌距离为1,每张骨牌有其高度和推倒的花费,问最少的花费推倒所有的骨牌。

题解:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+1000;

ll n,m,siz[N],h[N],L[N],R[N],c[N],dp[N];
vector<ll>H[N],C[N];
int s[N],r;

int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        scanf("%lld",&siz[i]);
        H[i].resize(siz[i]);
        C[i].resize(siz[i]);
        for(int j=0;j<siz[i];j++) scanf("%lld",&H[i][j]);
        for(int j=0;j<siz[i];j++) scanf("%lld",&C[i][j]);
    }
    int Q;cin>>Q;
    int cnt=0;
    while(Q--) {
        int id,mul;scanf("%d%d",&id,&mul);
        for(int j=0;j<siz[id];j++) h[++cnt]=H[id][j],c[cnt]=C[id][j]*mul;
    }
    for(int i=1;i<=m;i++) {
        while(r&&h[s[r]]+s[r]<=i)
            R[s[r--]]=i-1;
        s[++r]=i;
    }
    while(r) R[s[r--]]=m;
    for(int i=m;i;i--) {
        while(r&&s[r]-h[s[r]]>=i)
            L[s[r--]]=i+1;
        s[++r]=i;
    }
    while(r) L[s[r--]]=1;

    for(int i=1;i<=m;i++) {
        dp[i]=c[i]+dp[L[i]-1];
        while(r&&R[s[r]]<i) r--;
        if(r) dp[i]=min(dp[i],c[s[r]]+dp[s[r]-1]);
        ll cost=c[i]+dp[i-1];
        if(r&&cost<c[s[r]]+dp[s[r]-1]||!r)
            s[++r]=i;
    }
    cout<<dp[m];
}
View Code

 

标签:Shark,int,Dangerous,花费,推倒,dp,骨牌,单调
来源: https://www.cnblogs.com/bxd123/p/12234275.html