[CF321E] Ciel and Gondolas

前言

决策单调性得好好学。

理解不深,瞎掰扯。

题目

洛谷

CF

讲解

经典题。

这道题的决策单调性可以由四边形不等式证明,形如 \(w(a,c)+w(b,d)\le w(a,d)+w(b,c) (a\le b<c\le d).\)

决策单调性可以用分治快速求解,我们考虑分 \(k'\) 块,显然其只和 \(k'-1\) 有关,所以我们一层一层解决问题。

具体的,我们每次二分一个中点,求出它的最优决策点,然后左右两个区间分别递归下去,顺便改一下决策区间,根据决策单调性即可满足复杂度。

时间复杂度 \(O(nk\log_n)\)。

代码

原谅我的工地英语
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 4005;
const int INF = 0x3f3f3f3f;
int n,m;
int pre[MAXN][MAXN],dp[MAXN][MAXN];

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int now;
int Sum(int l,int r){return (pre[r][r]-pre[l-1][r]-pre[r][l-1]+pre[l-1][l-1]) >> 1;}
void solve(int l,int r,int ql,int qr)//section to be solved,operation section
{
	if(l > r) return;
	int mid = (l+r) >> 1,ID = ql,MIN = INF;
	for(int i = ql,val;i <= qr && i <= mid;++ i)
		if((val = Sum(i,mid)+dp[i-1][now-1]) < MIN)
		{
			MIN = val;
			ID = i;
		}
	dp[mid][now] = MIN;
	solve(l,mid-1,ql,ID);
	solve(mid+1,r,ID,qr);
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read();
	for(int i = 1;i <= n;++ i)
		for(int j = 1;j <= n;++ j)
			pre[i][j] = pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+Read();
	memset(dp,INF,sizeof(dp));
	dp[0][0] = 0;
	for(now = 1;now <= m;++ now) solve(1,n,1,n);
	Put(dp[n][m],'\n');
	return 0;
}
上一篇:sql分组后取每组前三


下一篇:[提高组集训2021] 超级加倍