题目大意:
从矩阵的左上角走到右下角,求走过的最小方差路径的方差*(n-m+1)^2
思路:
可以知道方差可以表示为平方和的平均数-平均数的平方
化简公式得到平方的和*(n+m-1)-路径上的权值和的平方
三维dp i j k表示走到i j位置 路径上经过的权值和为k的最小平方和
然后正常的转移
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 using namespace std; 12 inline int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 16 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 17 return x*f; 18 } 19 int T,mp[35][35],n,dp[35][35][60*30],m,ans; 20 int main() 21 { 22 T=read(); 23 for(int t=1;t<=T;t++) 24 { 25 printf("Case #%d: ",t); 26 n=read(),m=read(); 27 for(int i=1;i<=n;i++) 28 for(int j=1;j<=m;j++) mp[i][j]=read(); 29 memset(dp,127,sizeof(dp));dp[1][1][mp[1][1]]=mp[1][1]*mp[1][1]; 30 for(int i=1;i<=n;i++) 31 for(int j=1;j<=m;j++) 32 for(int k=0;k<=59*30;k++) 33 if(dp[i][j][k]!=inf) 34 { 35 if(i<n) dp[i+1][j][k+mp[i+1][j]]=min(dp[i][j][k]+mp[i+1][j]*mp[i+1][j],dp[i+1][j][k+mp[i+1][j]]); 36 if(j<m) dp[i][j+1][k+mp[i][j+1]]=min(dp[i][j+1][k+mp[i][j+1]],dp[i][j][k]+mp[i][j+1]*mp[i][j+1]); 37 } 38 ans=inf; 39 for(int i=0;i<=59*30;i++) 40 if(dp[n][m][i]!=inf) ans=min(ans,(n+m-1)*dp[n][m][i]-i*i); 41 printf("%d\n",ans); 42 } 43 }