hdu 5492(dp)

题目描述:

给定一张30*30的图,图上每个点的权值不超过30,让你求

(N+M−1)∑N+M−1i=1(Ai−Aavg)2的最小值?

队友将这个式子化成了求方差D[x]=E(x^2)-E(x);

我猜测是DP,分析一下,这个式子并不具有最优子结构,假设可以经过A和B

到达终点c,选取这两个点的方差的最小值,说明到达这两个点的序列最稳定,

假设A点是较优点,但是可能会出现,到达A点的最优序列加上c的序列,

没有到达A的某一个序列加上c的序列优(稳定)。

可以直接化简这个式子得到(A1^2+A2^2+A3^2+...+A[n+m-1]^2)*(n+m-1)-(A1+A2+A3+A4+...+A[n+m-1])^2;

观察一下我们可以维护和和平方和这两项,然后将到达某一个点的所有可能路径

,通过和来分类,d[x][y][k]表示到达x,y这个点和为k的最小平方和。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <queue>
#define maxn 31
#define  LL long long
#define inf 0x3f3f3f3f3f3f
using namespace std;
int ans;
int d[maxn][maxn][1800];
int a[maxn][maxn];
int dir[2][2]={1,0,0,1};
int n,m;
struct node
{
    int x,y,k;
};
void init()
{
   for(int i=0;i<maxn;i++)
    for(int j=0;j<maxn;j++)
      for(int k=0;k<1800;k++)
        d[i][j][k]=inf;
}
void spfa()
{
    int visit[maxn][maxn];
    memset(visit,0,sizeof(visit));
    queue <node>  que;
    node start;
    start.x=1;  start.y=1;  start.k=a[1][1];
    d[1][1][a[1][1]]=a[1][1]*a[1][1];
    que.push(start);
    visit[1][1]=1;
    while(!que.empty())
    {
        node next,cur=que.front();   que.pop();
        for(int i=0;i<2;i++)
        {
            int x,y,k;
            next.x=x=cur.x+dir[i][0];
            next.y=y=cur.y+dir[i][1];
            next.k=k=cur.k+a[x][y];
            if(next.x>=1 && next.x<=n && next.y>=1 && next.y<=m)
            {
                int temp=d[cur.x][cur.y][cur.k]+a[x][y]*a[x][y];
                if(temp<d[x][y][k])
                {
                   d[x][y][k]=temp;
                    if(visit[x][y]==1)
                        continue;
                    que.push(next);
                    visit[1][1]=1;
                }
            }
        }
    }
}
int main()
{
    // freopen("test.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int  t;
    scanf("%d",&t);
    int cas = 0;
    while(t --)
    {
        init();
         scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
             scanf("%d",&a[i][j]);
        //work();
        spfa();
        ans=inf;
        for(int k=0;k<=30*59;k++)
        {
           if(d[n][m][k]==inf)
            continue;
           int temp=(n+m-1)*d[n][m][k]-k*k;
           if(temp<=ans && temp>=0)
                ans=temp;
        }
        printf("Case #%d: %d\n",++cas,ans);
    }
    return 0;
}
时间: 2024-10-11 10:19:56

hdu 5492(dp)的相关文章

HDU 5492(DP) Find a path

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5492 题目大意是有一个矩阵,从左上角走到右下角,每次能向右或者向下,把经过的数字记下来,找出一条路径是这些数的方差最小. Find a path Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 961    Accepted Submissi

HDU 4832(DP+计数问题)

HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行,竖用几行,然后相乘累加起来就是答案 代码: #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long ll; const ll MOD = 9999991; const int N = 1005; int t, n, m, k, x, y; ll dp1

hdu 3944 dp?

DP? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 128000/128000 K (Java/Others)Total Submission(s): 1804    Accepted Submission(s): 595 Problem Description Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0,1,2,-a

hdu 5389 dp类似背包

http://acm.hdu.edu.cn/showproblem.php?pid=5389 Problem Description Zero Escape, is a visual novel adventure video game directed by Kotaro Uchikoshi (you may hear about ever17?) and developed by Chunsoft. Stilwell is enjoying the first chapter of this

hdu 1025 dp 最长上升子序列

1 //Accepted 4372 KB 140 ms 2 //dp 最长上升子序列 nlogn 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 500005; 8 int dp[imax_n]; 9 int d[imax_n]; 10 int a[imax_n]; 11 int n; 12 int len

HDU 5928 DP 凸包graham

给出点集,和不大于L长的绳子,问能包裹住的最多点数. 考虑每个点都作为左下角的起点跑一遍极角序求凸包,求的过程中用DP记录当前以j为当前末端为结束的的最小长度,其中一维作为背包的是凸包内侧点的数量.也就是 dp[j][k]代表当前链末端为j,其内部点包括边界数量为k的最小长度.这样最后得到的一定是最优的凸包. 然后就是要注意要dp[j][k]的值不能超过L,每跑一次凸包,求个最大的点数量就好了. 和DP结合的计算几何题,主要考虑DP怎么搞 /** @Date : 2017-09-27 17:27

HDU 4901 DP背包

给你n个数,问你将数分成两个数组,S,T ,T 中所有元素的需要都比S任意一个大,问你S中所有元素进行 XOR 操作和 T 中所有元素进行 &操作值相等的情况有多少种. DP背包思路 dpa[i][j][0]  表示从左开始到i,不取i,状态为j的方案数 dpa[i][j][1]  表示从作开始到i,取i,状态为j的方案数 dpb[i][j]      表示从右开始到i,状态为j的方案数 因为S集合一定在T集合的左边,那么可以枚举集合的分割线,并且枚举出的方案要保证没有重复,如果要保证不重复,只

HDU 5492 Find a path DP

Find a path Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5492 Description Frog fell into a maze. This maze is a rectangle containing N rows and M columns. Each grid in this maze contains a number, which is cal

hdu 5492 网格图dp

#include<stdio.h> #include <math.h> #include <algorithm> #include <math.h> #include <string.h> #include <bitset> #include <iostream> using namespace std; #define LL long long int n,m,k; int a[31][31]; int f[31][31