首页 > 其他分享 >做题记录整理dp15 P1772. [ZJOI2006] 物流运输(2022/9/28)

做题记录整理dp15 P1772. [ZJOI2006] 物流运输(2022/9/28)

时间:2022-09-29 17:11:51浏览次数:72  
标签:dl 2022 28 vis tl pd printf ZJOI2006 dp15

P3648 [APIO2014] 序列分割
第一次做斜率优化的题
题解看懂了,但没有完全看懂
等以后得回来看一次

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
ll n,k,vis[205][100007];
ll s[100007],f[100007],g[100007];
int dl[100007],hd,tl;
double pd(int x,int y) 
{
	ll x1=-s[x];
	ll y1=g[x]-s[x]*s[x];
	ll x2=-s[y];
	ll y2=g[y]-s[y]*s[y];
	if(x1==x2) return -1e10;
	return (double)((double)(y2-y1)/(double) (x2-x1));
}
int main() 
{
	scanf("%lld%lld",&n,&k);
	for1(i,1,n)
	 {
		scanf("%lld",&s[i]);
		s[i]+=s[i-1];
	}
	ll ji;
	for1(t,1,k)
	 {
		for1(i,1,n) g[i]=f[i]; 
		hd=tl=0;
		for1(i,1,n)
		 {
			while(tl-hd>=2&&pd(dl[hd],dl[hd+1])<=s[i])  hd++;
			f[i]=0;
			if(hd<tl)
			{
				ji=dl[hd];
				vis[t][i]=ji;
				f[i]=g[ji]+s[ji]*(s[i]-s[ji]);
			}
			while(tl-hd>=2&&pd(dl[tl-1],dl[tl-2])>=pd(i, dl[tl-1])) tl--;
			dl[tl++]=i;
		}
	}
	printf("%lld\n",f[n]);
	ll i=vis[k][n];
	while(k)
	{
		printf("%lld ",i),
		i=vis[--k][i];
	}
	return 0;
}

标签:dl,2022,28,vis,tl,pd,printf,ZJOI2006,dp15
From: https://www.cnblogs.com/yyx525jia/p/16742233.html

相关文章