您的位置:首页 > 其它

JZOJ5453. 【NOIP2017提高A组冲刺11.5】好路线

2017-11-06 15:59 351 查看

题目





题解

题目的意思就是要最小化方差,就是要波动最小。

先来解释一下,最后的答案为什么是整数

设s=∑ki=1xi

那么x=sk

a2=k2∗∑ki=1x2i−2∗xi∗sk+s2k2k

拆开这个式子:

a2=k∗(∑ki=1x2i)−(∑ki=1xi)2

数据中,∑ki=1xi很小,可以将它设进dp的状态里面。

设fi,j,k表示当前的位置是(i,j),选择x的和是k时的最小的∑ki=1x2i

转移就很简单了。

code

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define N 53
using namespace std;

int n,m,f

[5000],h

,ans;

char ch;
void read(int& n)
{
n=0;
for(ch=getchar();ch<'0' || ch>'9';ch=getchar());
for(;'0'<=ch && ch<='9';n=(n<<3)+(n<<1)+ch-48,ch=getchar());
}

int main()
{
freopen("route.in","r",stdin);
freopen("route.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
read(h[i][j]);

memset(f,127,sizeof(f));
f[0][1][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=h[i][j];k<=4950;k++)
{
f[i][j][k]=min(f[i-1][j][k-h[i][j]],f[i][j-1][k-h[i][j]]);
if(f[i][j][k]<250000)f[i][j][k]+=h[i][j]*h[i][j];
}

ans=2147483647;
for(int i=0;i<=4950;i++)
if(f
[m][i]<250000)ans=min(ans,f
[m][i]*(n+m-1)-i*i);
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划