hdu 5492 Find a path

题目大意:

从矩阵的左上角走到右下角,求走过的最小方差路径的方差*(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 }
View Code

 

posted @ 2018-03-26 19:43  jack_yyc  阅读(128)  评论(0编辑  收藏  举报