[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 }