HDU 5492 Find a path

题意:

在一张N*M的图上,每个点都有权值,寻找一条从(1,1)到(n,m)的路径,使得

(n+m-1)*sigma(Ai-Aavg)最小

其中Aavg是路径上Ai的平均数

题解

看题目是一个DP,但是路径平均值得存在使得状态很难定义。

所以我们进行变形,将和式展开之后,得到ans=(n+m-1)*S1-S2;

其中S1是路径上所有数的平方和,S2为路径上数的和的平方。

也就是要求S1最小的同时S2最大。

dp[i][j][s]表示到达(i,j)时平方和为s时和的的最小值,答案通过枚举所有s取得

#include<bits/stdc++.h>

#define clr(x,y) memset((x),(y),sizeof(x))

using namespace std;
typedef long long LL;

const int maxn=30;
const int inf=1e8;

int mp[maxn+5][maxn+5];
int dp[maxn+5][maxn+5][2*maxn*maxn+5];
int n,m;

void solve(int iCase)
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i)
    {
        for (int j=1;j<=m;++j)
        {
            scanf("%d",&mp[i][j]);
        }
    }

    for (int i=1;i<=n;++i)
        for (int j=1;j<=m;++j)
            for (int k=0;k<=2*maxn*maxn;++k)
                dp[i][j][k]=inf;

    dp[1][1][mp[1][1]]=mp[1][1]*mp[1][1];
    for (int i=1;i<=n;++i)
    {
        for (int j=1;j<=m;++j)
        {
            if (i==1 && j==1) continue;
            for (int k=0;k<=2*maxn*maxn;++k)
            {
                if (i-1>=1 && k>=mp[i][j])
                    dp[i][j][k]=min(dp[i][j][k],dp[i-1][j][k-mp[i][j]]+mp[i][j]*mp[i][j]);
                if (j-1>=1 && k>=mp[i][j])
                    dp[i][j][k]=min(dp[i][j][k],dp[i][j-1][k-mp[i][j]]+mp[i][j]*mp[i][j]);
            }
        }
    }

    int ans=inf;
    for (int k=0;k<=2*maxn*maxn;++k)
    {
        if (dp[n][m][k]==inf) continue;
        int tmp=(n+m-1)*dp[n][m][k]-k*k;
        ans=min(ans,tmp);
    }
    printf("Case #%d: %d
",iCase,ans);
}

int main(void)
{
    #ifdef ex
    freopen ("../in.txt","r",stdin);
    //freopen ("../out.txt","w",stdout);
    #endif

    int T;
    scanf("%d",&T);

    for (int i=1;i<=T;++i)
    {
        solve(i);
    }
}
原文地址:https://www.cnblogs.com/123-123/p/5862468.html