zoukankan      html  css  js  c++  java
  • 【BZOJ4953】lydsy七月月赛 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+jover 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;
    }
  • 相关阅读:
    第一次结对作业
    第二次个人编程作业
    第一次个人编程作业
    第一次个人作业
    个人总结-人生如戏
    第二次结对编程
    第一次结对作业
    第二次个人编程作业:代码互改
    第一次个人编程作业
    软件工与UML程第一次作业
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7265395.html
Copyright © 2011-2022 走看看