求助单调队列优化
  • 板块灌水区
  • 楼主expnoi
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/5/15 10:00
  • 上次更新2023/10/28 01:24:37
查看原帖
求助单调队列优化
378346
expnoi楼主2022/5/15 10:00

不用O(n^3)朴素dp做,求助单调队列优化。

https://www.acwing.com/problem/content/4421/

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[5001],dp[5001][5001],k,x,q[5001][5001],ql[5001],qr[5001];
signed main()
{
    cin>>n>>k>>x;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        ql[i]=1;
        qr[i]=0;
    }
    memset(dp,0x80,sizeof(dp));
    //q[i][1]表示选了i个数的最优值
    dp[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=x;j++)
        {
            while(ql[j]<=qr[j]&&i-q[j][ql[j]]>k)ql[j]++;
        }
        for(int j=1;j<=min(i,x);j++)
        {
            if(j>1)
            {
                dp[i][j]=max(dp[i][j],dp[q[j-1][ql[j-1]]][j-1]+a[i]);
                if(dp[i][j]==11)
                cout<<"qaq  "<<q[j-1][ql[j-1]]<<'\n';
            }
            else
            {
                if(i<=k)
                {
                    dp[i][j]=a[i];
                }
            }
            /*if(dp[i][j]==10)
            {
                cout<<"qaq:"<<q[j-1][ql[j-1]]<<"\n";
            }*/
            while(ql[j]<=qr[j]&&dp[i][j]>=dp[q[j][qr[j]]][j])
            {
                qr[j]--;
                //cout<<"i:"<<i<<"   j: "<<j<<"    "<<"dp[i][j]:"<<""<<dp[i][j]<<"    ql[j]:"<<ql[j]<<"     qr[j]:"<<qr[j]<<"  dp[qr[j]][j] "<<dp[qr[j]][j]<<"\n";
            }
            q[j][++qr[j]]=i;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cout<<dp[i][j]<<" ";
        }
        cout<<endl;
    }
    int res=-1;
    for(int i=n-k+1;i<=n;i++)
    {
        res=max(res,dp[i][x]);
    }
    cout<<res;
}
2022/5/15 10:00
加载中...