Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1536    Accepted Submission(s): 673


Problem Description
Frog fell into a maze. This maze is a rectangle containing 2
In Frog's opinion, the smaller, the better. A path with smaller beauty value is more beautiful. He asks you to help him find the most beautiful path.  
 

 

Input
The first line of input contains a number M non-negative integers, indicating the magic values. The magic values are no greater than 30.
 

 

Output
For each test case, output a single line consisting of “Case #X: Y”. Y is the minimum beauty value.
 

 

Sample Input
1 2 2 1 2 3 4
 

 

Sample Output
Case #1: 14
 

 

Source

题意:(1,1)到(n,m)向右向下的最小方差路径

把方差的式子化简推理,得到
(n+m-1)*Σai^2-(Σai)^2   i belong path
注意两者平方位置演算时写清了
f[i][j][k]表示到(i,j)和为k的最小平方和,递推就行了
//
//  main.cpp
//  hdu5492
//
//  Created by Candy on 10/2/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std;
const int N=35,INF=1e9;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int T,n,m,l,a[N][N],f[N][N][N*2*30];
int dp(){
    memset(f,127,sizeof(f));
    f[1][1][a[1][1]]=a[1][1]*a[1][1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            for(int k=0;k<=l*30;k++)
                if(f[i][j][k]<=INF){
                    int x=i+1,y=j,w=a[x][y];
                    f[x][y][k+w]=min(f[x][y][k+w],f[i][j][k]+w*w);
                    x=i;y=j+1;w=a[x][y];
                    f[x][y][k+w]=min(f[x][y][k+w],f[i][j][k]+w*w);
                }
    int ans=INF;
    for(int k=0;k<=l*30;k++)
        if(f[n][m][k]<INF)
            ans=min(ans,l*f[n][m][k]-k*k);
    return ans;
}
int main(int argc, const char * argv[]) {
    T=read();int cas=0;
    while(T--){
        n=read();m=read();l=n+m-1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) a[i][j]=read();
        printf("Case #%d: %d\n",++cas,dp());
    }

    return 0;
}

 

 

相关文章: