[HDU5492]Find a path

题目大意:
  一个n*m的格子,每个格子上都有一个数。
  你可以向下或者向右走,从(1,1)走到(n,m),问方差*(n+m-1)最小的路径是哪个?

思路:
  方差*(n+m-1)就相当于给格子里每个数乘上(n+m-1)再求方差。
  由于数据范围较小,我们可以直接枚举每个平均数,再求一条方差最小的路径。
  不用担心平均数和所走的路径不对应的情况。
  因为就算这次的平均数和路径不对应,我们还是可以再下一次枚举到正确的平均数,而用正确的平均数算的方差显然是更小的。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 inline int getint() {
 5     register char ch;
 6     while(!isdigit(ch=getchar()));
 7     register int x=ch^'0';
 8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 9     return x;
10 }
11 const int inf=0x7fffffff;
12 const int N=32,M=32;
13 int a[N][M],f[N][M];
14 int n,m;
15 inline int sqr(const int &x) {
16     return x*x;
17 }
18 inline void dp(const int &avg) {
19     std::fill(&f[0][0],&f[n][m+1],inf);
20     f[1][1]=sqr(a[1][1]*(n+m-1)-avg);
21     for(register int i=1;i<=n;i++) {
22         for(register int j=1;j<=m;j++) {
23             f[i+1][j]=std::min(f[i+1][j],f[i][j]+sqr(a[i+1][j]*(n+m-1)-avg));
24             f[i][j+1]=std::min(f[i][j+1],f[i][j]+sqr(a[i][j+1]*(n+m-1)-avg));
25         }
26     }
27 }
28 int main() {
29     const int T=getint();
30     for(register int i=1;i<=T;i++) {
31         printf("Case #%d: ",i);
32         n=getint(),m=getint();
33         for(register int i=1;i<=n;i++) {
34             for(register int j=1;j<=m;j++) {
35                 a[i][j]=getint();
36             }
37         }
38         int ans=inf;
39         for(register int i=0;i<=1770;i++) {
40             dp(i);
41             ans=std::min(ans,f[n][m]/(n+m-1));
42         }
43         printf("%d\n",ans);
44     }
45     return 0;
46 }

 

posted @ 2017-10-26 16:11  skylee03  阅读(124)  评论(0编辑  收藏  举报