zoukankan      html  css  js  c++  java
  • CF1077F2 Solution

    题目链接

    题解

    仅在easy version上增加单调队列优化即可,简单版题解。但注意为使单调队列中数据为之前卡牌,需要倒序转移(与01背包滚动数组相似)。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=5001,inf=0x3f3f3f3f3f3f3f3f;
    int a[N],dp[N][N],tl[N],hd[N],q[N][N];
    //q[i][]:当前dp[][i](已选出i张)的单调队列,hd/tl[i]:q[i][]的队首/队尾
    signed main()
    {
    	int k,x,n,ans=-inf;
    	scanf("%lld%lld%lld",&n,&k,&x);
    	memset(dp,-0x3f,sizeof(dp));
    	for(int i=1;i<=n;i++) {scanf("%lld",&a[i]); dp[i][0]=0;}
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=min(i,x);j>=2;j--)
    		{
                //需先删头后去尾(与模板不同)
    			while(q[j-1][hd[j-1]]<i-k && hd[j-1]<=tl[j-1]) hd[j-1]++;
    			if(hd[j-1]<=tl[j-1]) dp[i][j]=dp[q[j-1][hd[j-1]]][j-1]+a[i];
    			while(dp[q[j][tl[j]]][j]<dp[i][j] && hd[j]<=tl[j]) tl[j]--;
    			q[j][++tl[j]]=i;
    		}
    		if(i<=k) 
    		{
    			dp[i][1]=a[i];
    			while(dp[q[1][tl[1]]][1]<dp[i][1] && hd[1]<=tl[1]) tl[1]--;
    			q[1][++tl[1]]=i;
    			while(q[1][hd[1]]<i-k && hd[1]<=tl[1]) hd[1]++;
    		} 
    	}
    	for(int i=n-k+1;i<=n;i++) ans=max(ans,dp[i][x]);
    	if(ans<0) printf("-1");
    	else printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    Markdown语法
    Hello World
    sql笔试题-1
    解决高版本vm打开虚拟机报错
    zookeeper启动闪退
    java找出1~1000中素数的三种方式
    Java中更精确的计时
    vue系列之调试工具(vue-devtools)
    vue系列之npm命令错误
    vue系列之安装基础环境
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14607433.html
Copyright © 2011-2022 走看看