BZOJ4953lydsy七月月赛 F DP

Posted CQzhangyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ4953lydsy七月月赛 F DP相关的知识,希望对你有一定的参考价值。

【BZOJ4953】lydsy七月月赛 F

题面

题解:设f[i][j]表示第i个强度取为j时的最小误差。那么每次转移时,我们只计算j‘和j之间的像素点带来的误差,于是有:

$f[i][j]=min(f[i-1][k]+g(k..mid,k)+g(mid+1...j,j))|mid={k+j\over 2}$

其中,&g(a,b)=P_a*(a-b)^2\\=P_a*a*a-2*P_a*a*b+2*P_a*b*b&

于是维护P_a*a*a,P_a*a,P_a的前缀和即可。

 

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
ll s0[300],s1[300],s2,f[300][300],ans;
int n,m;
int main()
{
	scanf("%d%d",&n,&m);
	int i,j,k,mid;
	for(i=1;i<=n;i++)	scanf("%d",&j),scanf("%lld",&s0[j]),s1[j]=j*s0[j],s2+=j*j*s0[j];
	for(i=1;i<=255;i++)	s0[i]+=s0[i-1],s1[i]+=s1[i-1];
	memset(f,0x3f,sizeof(f));
	ans=1ll<<60;
	for(i=1;i<=m;i++)
	{
		if(i==1)	for(j=0;j<=255;j++)	f[1][j]=s0[j]*j*j-2*s1[j]*j;
		else	for(j=i-1;j<=255;j++)
		{
			for(k=i-2;k<j;k++)
			{
				mid=j+k>>1;
				f[i][j]=min(f[i][j],f[i-1][k]+(s0[mid]-s0[k])*k*k+(s0[j]-s0[mid])*j*j-2*(s1[mid]-s1[k])*k-2*(s1[j]-s1[mid])*j);
			}
		}
		if(i==m)
			for(j=i-1;j<=255;j++)	f[i][j]+=(s0[255]-s0[j])*j*j-2*(s1[255]-s1[j])*j,ans=min(ans,f[i][j]);
	}
	printf("%lld",ans+s2);
	return 0;
}

 

以上是关于BZOJ4953lydsy七月月赛 F DP的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4950lydsy七月月赛 C 二分图最大匹配

BZOJ5073[Lydsy十月月赛]小A的咒语 DP

bzoj 5072 [Lydsy1710月赛]小A的树——树形dp

bzoj5123[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

BZOJ4919[Lydsy六月月赛]大根堆

[Bzoj5359][Lydsy1805月赛]寻宝游戏(dp)