您的位置:首页 > 其它

2017.7.31 征途 失败总结

2017-07-31 22:35 155 查看
、这题其实是一步分析错了,所以一直wa

首先要求方差,就是要求   Σ(ai-V平均)^2     当然还要除以m  (第一遍忘了除,第二遍除的是n、、)

平均数就是总和再除以m

这可能不能用小数 示完,所以就考虑拆成分数,这样算到最后一步分母是m^3(一个平方+数的个数)

因为要输出v*m^2所以直接分子/m就好了

然后转移是   f【i】【j】=min(f【i-1】【k】+(qsum【j】-qsum【k】-v平均)^2)

拆开就可以写出直线方程:

2*qsum【j】*qsum【k】*m*m+f【j】+2*qsum【j】*m*qsum【n】-m*m=f【k】+q【k】*q【k】*qsum【n】*qsum【n】+2*qsum【k】*m*qsum【n】;

然后在n*m的做就行了     设v1=qsum【n】 v2=m;    纯粹为了方便

要注意枚举的时候从上一层转移,所以移动l++用当前层(用现在的状态调整状态的选取)  r--要用上一层(加入一个选择,并维护状态的凸包形态)

另外枚举的时候尽量避免枚举k,而加减却要用k-1的情况(自找麻烦,而且容易遗漏)

对于有一天没走路的情况,可以通过递推避免,如果f【1】【0】==inf   拿后来的f【2】【1】也将由f【1】【0】转移来,==inf   所以细节需要处理,保证每一天都走

码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,m,a[3005],qsum[3005],v1,v2,f[3005][3005],l,r,q[3005];
double xl(int ceng,long long a,long long b)
{
return (double(f[ceng][b]-f[ceng][a]+qsum[b]*qsum[b]*v2*v2-qsum[a]*qsum[a]*v2*v2+2*(qsum[b]-qsum[a])*v1*v2)/double(qsum[b]-qsum[a]));
}

int main()
{
memset(f,0x6f,sizeof(f));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),v1+=a[i],qsum[i]=qsum[i-1]+a[i];
v2=m;
f[0][0]=0;
for(int i=1;i<=n;i++)
f[1][i]=(qsum[i]*v2-v1)*(qsum[i]*v2-v1);
for(int i=2;i<=m;i++)
{
l=1;
r=1;
q[1]=0;
for(int j=1;j<=n;j++)
{ while(l<r&&(xl(i-1,q[l],q[l+1])<=(2*qsum[j]*v2*v2)))l++;
int k=q[l];
f[i][j]=f[i-1][k]+(qsum[j]*v2-qsum[k]*v2-v1)*(qsum[j]*v2-qsum[k]*v2-v1);
while(l<r&&(xl(i-1,q[r-1],q[r])>xl(i-1,q[r],j)))r--;
q[++r]=j;
}
}

printf("%lld",f[m]
/m);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: