【NOIP2017提高组】好路线

来源:互联网 发布:土豆for mac 编辑:程序博客网 时间:2024/05/22 10:39

Description

这里写图片描述

Solution

很容易的DP。
先把式子化简可以发现变成了(a12+a22+......+ak2)k(ai)2,后面的部分可以作为DP的其中一维状态,设成后面的值确定时,前一部分的值最小的情况。

Code

#include<algorithm>#include<math.h>#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define fo(i,a,b) for(i=a;i<=b;i++)typedef long long ll;const int N=52;ll f[N][N][2*N*N],a[N][N],INF,ans;ll n,m,i,j,k,K,mx;ll sqr(ll x){return x*x;}int main(){    scanf("%lld%lld",&n,&m);    fo(i,1,n) fo(j,1,m) scanf("%lld",&a[i][j]),mx=max(mx,a[i][j]);    K=n+m-1;mx*=K;    memset(f,127/2,sizeof(f));INF=f[0][0][0];    fo(i,1,n) fo(j,1,m){        if(i==1&&j==1){            f[i][j][a[i][j]]=sqr(a[i][j]);            continue;        }        fo(k,0,mx){            if(i>1&&k-a[i][j]>=0&&f[i-1][j][k-a[i][j]]<INF)                f[i][j][k]=min(f[i][j][k],f[i-1][j][k-a[i][j]]+sqr(a[i][j]));            if(j>1&&k-a[i][j]>=0&&f[i][j-1][k-a[i][j]]<INF)                f[i][j][k]=min(f[i][j][k],f[i][j-1][k-a[i][j]]+sqr(a[i][j]));        }    }    ans=INF;fo(k,0,mx) if(f[n][m][k]<INF)ans=min(ans,f[n][m][k]*K-sqr(k));    printf("%lld\n",ans);}
原创粉丝点击