首页 > 其他分享 >Codeforces Round 892 (Div. 2) E

Codeforces Round 892 (Div. 2) E

时间:2024-04-25 12:12:52浏览次数:21  
标签:892 Codeforces leq 绝对值 Div calc 优化 维护 dp

E的话一眼dp,然后观察一下方程,\(f[i][j]表示前i个位置已经选了长度为j的区间,且第i个位置已经被选上时,能够获得的最大值\)

\[f[i][j]=\displaystyle\max_{1\leq k\leq min(i,j)}(f[i-k][j-k]+calc(i-k+1,j))\\ calc(l,r)=|b_l-a_r|+|b_r-a_l| \]

这样的dp是\(O(n^2k)\)的,而\(1\leq k\leq n\leq 3000\),我们需要优化到\(O(n^2log(n))\)这个级别。

观察dp,考虑优化,正常情况下,优化的部分都是枚举k的部分,我们对每次转移分开考虑,假如我不需要再去枚举k,而是直接通过数据结构查询得到就可以了。

发现\(f[i-k][j-k]\)是一个很有规律的东西,转化为图形,就是在dp数值组成的表里面斜率为1的直线通过的点。而这个很明显是可以维护的,问题就在后面的\(calc\)的代价函数中

我们现在的\(f[i-k][j-k]\)可以被单独维护,导致我们必须枚举k的东西是calc中含有k的部分,假如这部分不存在,那么其实直接维护\(f[i-k][j-k]和后面剩下部分的\)的\(max\)即可,对于绝对值也是随便处理,因为这个值其实是固定的。
而含有和k相关的部分,这导致先前使用过的,已经维护好的\(f[i-k][j-k]\)的最大值并不能直接套用,我们必须考虑新的一位和前面部分的结合而形成的绝对值的影响。

假如把绝对值去掉,是否能做呢?
可以。而且很好做。观察发现,其实\(calc\)函数中含有\(k\)的部分是和\(f[i-k][j-k]\)绑定的,这个其实从题目中对价值的描述中可以更好的看出来。也就是说,我们其实是直接维护了这个式子含有k的所有部分一同的最大值,这个很好,因为剩下的只和\(i,j\)相关的部分的值是确定的,也就是说我们需要的东西就直接\(O(1)\)维护好了。
而这个只是没有绝对值的情况,绝对值这个东西也不算难处理,直接分类讨论,拆开,我们两个绝对值一共4中情况。而事实上也不用分开维护,仔细考虑一下,加上绝对值只会让答案变大,所以直接取max,根本就可能取到不合法的情况的值。否则没法维护。这不是一个普通的偏序。这一点很巧妙。

不错的dp,分析这个代价函数的内容是情理之中,而这个代价函数中和\(f[i-k][j-k]\)强相关的部分是要从题目中理解得到的,这算是一个小难点。其实拆开绝对值的操作也是很合理的,想要优化这个dp,无非就是从状态和转移两方面下手,所有的dp都是这么优化的,而状态的优化其实是对应了前两个循环,这很显然很难办到,那就是加速转移。想要加速转移,那拆开这个绝对值就是必要的思路。

这边就给我提供了一个很好的思路,先假设绝对值不存在,然后再考虑。

还算简单的一个dp优化吧。这题居然能有2500。那9062E2居然只有2600。这两题之间的难度差距真心挺大。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
	ll a=0,b=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
	return a*b;
}
ll n,K,a[3021],b[3021],f[3021][3021];
ll Max[3021][3021][5];
ll s1[5]={0,+1,-1,+1,-1},s2[5]={0,-1,-1,+1,+1};
int main()
{
	ll T=read();
	while(T--)
	{
		n=read(),K=read();
		for(ll i=1;i<=n;i++)a[i]=read();
		for(ll i=1;i<=n;i++)b[i]=read();
		for(ll i=0;i<=n;i++)
		{
			for(ll j=0;j<=K;j++)
			{
				f[i][j]=0;
				for(ll k=1;k<=4;k++)
				Max[i][j][k]=-(1LL<<60);
			}
		}
		for(ll i=1;i<=n;i++)
		{
			for(ll j=1;j<=K;j++)
			{
				f[i][j]=f[i-1][j];
				for(ll k=1;k<=4;k++)
						Max[i][j][k]=max(Max[i-1][j-1][k],f[i-1][j-1]+a[i]*s1[k]+b[i]*s2[k]);
				for(ll k=1;k<=4;k++)
						f[i][j]=max(f[i][j],Max[i][j][k]-a[i]*s2[k]-b[i]*s1[k]);
			}
		}
		cout<<f[n][K]<<endl;
	}
	return 0;
}

标签:892,Codeforces,leq,绝对值,Div,calc,优化,维护,dp
From: https://www.cnblogs.com/HLZZPawa/p/18157315

相关文章

  • cf 1601B Frog Traveler Codeforces Round 751 (Div. 1)
     Problem-1601B-Codeforces BFS然后每次上升可以的范围是一个区间,然后每次都遍历这个区间的所有点,那么超时。用set等方式,合并这些区间,之前没遍历过的范围才更新(加入BFS需要遍历的队列里)。但是区间的更新特别容易写错…… 我的代码和造数据1/**2记录两个vi......
  • Codeforces Round 940 (Div. 2) and CodeCraft-23 题解
    CodeforcesRound940(Div.2)andCodeCraft-23题解题目链接A.Stickogon贪心#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.end()#defineendl'\n'#definedebu......
  • Educational Codeforces Round 164 (Rated for Div. 2)
    A.PaintingtheRibbon题意:n个物体,m个颜色,alice要给每个物体任意涂一个颜色。bob可以给k个物体涂色,问alice能否阻止bob让所有的物体颜色都相同。思路:思维题。如果m=1,那么无解。如果m>1,那么bob如果想要染成同一个颜色,alice可以让bob需要染色的数量最多。如果染色的数量最多,那......
  • Codeforces Round 906 (Div. 2) E1
    时隔了不知道多久的补题。两个月吧,这是可是寒假的比赛。但是补题的时候还是遇到了很多问题。很重要的有一些地方能够简化,一些条件没有充分的利用上,导致了我很多地方考虑的太复杂。这些能够简化的地方全部利用上我觉得才算是写出来了这道题目,否则这题会复杂到我赛时写不完,而且特......
  • CodeForces 115D Unambiguous Arithmetic Expression
    洛谷传送门CF传送门直接区间dp可以做到\(O(n^3)\),卡常可过,在此就不赘述了。为了方便先把连续的数字缩成一段。我们考虑直接从前往后扫,扫的过程中dp。设\(f_{i,j}\)为考虑了\([1,i]\),还有\(j\)个没配对的左括号的方案数。但是我们发现我们不知道一个数字前要添加几......
  • CRound927__Div3__C
    这道题涉及到两个部分,先是逆向思维,正着做一定会无比困难,而倒过来想就会好做,也比较难想到逆向思维,见识又少了,倒着思考就得先找到最后一个移除的元素include<bits/stdc++.h>usingnamespacestd;defineforn(i,n)for(inti=0;i<int(n);i++)intmain(){intt;cin......
  • 给定两个数x和y(长度相等),让它们可以交换各个位上的数字(位对应交换),求让两数乘积最大的
    如题,给出x=73,y=31,如何让两数乘积最大?位数定义:各个位上的数字例73,位数有7,3当前,只有一种交换策略,x=71,y=33,发现交换以后有:x+y=x'+y',如果抽象成求最大面积就好办了,可能一下想不到,还得多积累经验,不是你不知道是你想不到是你见得少,没见识...当是正方形的时候面积最大小学......
  • Codeforces Round 940 (Div. 2) and CodeCraft-23
    A.Stickogon#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;#defineinti64usingvi=vector<int>;constintN=3e5,mod=1e9+7;voidsolve(){ vicnt(101); intn; cin>>n; for(i......
  • Codeforces Round 892 (Div. 2) 复盘
    A没啥好说的。B也是,很简单的贪心。但是AB都因为读题导致的理解误差wa了一发。哎,读题读错,只能说英语还得练。C,赛时没做出来,后面的也是。这个题目其实思路已经有了,cf的这种题,还放在C题,那就是很明显那种能打标看出规律的东西。就算知道了是打表能看出来的,我懒得写暴力,所以就一直......
  • Codeforces Round 940 (Div. 2) and CodeCraft-23
    CodeforcesRound940(Div.2)andCodeCraft-23前四题难度适中,总体还算不错,我想想都能做。E题考察威尔逊和质数筛前缀和算贡献。F题是数据结构,据说很版,还没补。A题:题意:给出n个木棍,最多组成多少个多边形Solution:统计各长度木棍的数量,全部贪心成三角形voidsolve(){ cin>>n;......