題意:矩陣中找一條路徑,是的路徑上的各個點的數值方差最小
解一:DP
將題中算是化簡可得(n+m-1)*segma(Ai^2)-(segma(Ai))^2
dp[i][j][k]表示到矩陣中i,j這個點和爲k的最小的Ai^2的和
dp[i][j+1][k+num[i][j+1]]=MIN(dp[i][j+1][k+num[i][j+1],dp[i][j][k]+num[i][j]*num[i][j])
#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
int dp[35][35][2000];
int num[35][35];
const int maxn=0x3f3f3f3f;
int sq(int x)
{
return x*x;
}
int main()
{
int t;
int n,m;
int minn;
while(scanf("%d",&t)!=-1)
{
for(int i=1;i<=t;i++)
{
scanf("%d%d",&n,&m);
for(int j=0;j<n;j++)
for(int k=0;k<m;k++)
{
scanf("%d",&num[j][k]);
for(int l=0;l<1800;l++)
dp[j][k][l]=maxn;
}
dp[0][0][num[0][0]]=sq(num[0][0]);
for(int j=0;j<n;j++)
for(int k=0;k<m;k++)
for(int l=0;l<1800;l++)
{
if(dp[j][k][l]!=maxn)
{
dp[j][k+1][l+num[j][k+1]]=MIN(dp[j][k+1][l+num[j][k+1]],dp[j][k][l]+sq(num[j][k+1]));
dp[j+1][k][l+num[j+1][k]]=MIN(dp[j+1][k][l+num[j+1][k]],dp[j][k][l]+sq(num[j+1][k]));
}
}
minn=maxn;
for(int j=0;j<1800;j++)
{
if(dp[n-1][m-1][j]!=maxn)
minn=MIN(minn,(n+m-1)*dp[n-1][m-1][j]-sq(j));
}
printf("Case #%d: %d\n",i,minn);
}
}
return 0;
}
解二:最小方差生成樹
學習中-0-