zoukankan      html  css  js  c++  java
  • 坐标DP 小奇的矩阵(matrix)

    问题 B: 小奇的矩阵(matrix)
    时间限制: 1 Sec 内存限制: 256 MB
    提交: 95 解决: 34
    [提交][状态]
    题目描述
    【题目背景】

    小奇总是在数学课上思考奇怪的问题。

    【问题描述】

    给定一个n*m的矩阵,矩阵中的每个元素aij为正整数。

    接下来规定

    1.合法的路径初始从矩阵左上角出发,每次只能向右或向下走,终点为右下角。

    2.路径经过的n+m-1个格子中的元素为A1,A2…A(n+m-1),Aavg为Ai的平均数,路径的V值为(n+m-1)*∑(Ai-Aavg) ^2

    (1<=i<=n+m-1)

    求V值最小的合法路径,输出V值即可,有多组测试数据。

    【输入格式】

    第一行包含一个正整数T,表示数据组数。

    对于每组数据:

    第一行包含两个正整数n和m,表示矩阵的行数和列数。
    接下来n行,每行m个正整数aij,描述这个矩阵。

    【输出格式】

    对于每次询问,输出一行一个整数表示要求的结果

    【样例输入】

    1

    2 2

    1 2

    3 4

    【样例输出】

    14
    【数据范围】

    对于30%的数据 n<=10,m<=10

    有另外40%的数据 n<=15 m<=15,矩阵中的元素不大于5

    对于100%的数据 T<=5,n<=30,m<=30,矩阵中的元素不大于30

    我貌似几个月没打过坐标DP了。。。
    把那个式子化简一下就是(n+m-1)*∑(ai^2)-(∑ai)^2
    但这个式子的值在走到一半时并无法确定是不是最优。但是ai<=30,加和最大只有1000几,那么把f数组加一维,枚举当前的sigma是多少就行了。最后算一遍。O(N^2*S)

    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int read()
    {
        int sum=0,f=1;char x=getchar();
        while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
        while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
        return sum*f;
    }
    int t,n,m,g,a[35][35],f[2005][35][35],ans;
    int main()
    {   
        t=read();
        while(t--)
        {
            memset(f,-1,sizeof(f));
            n=read();m=read();g=m+n-1;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    a[i][j]=read();
            f[a[1][1]][1][1]=a[1][1]*a[1][1];
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    for(int k=a[i][j];k<=1500;k++)
                    {
                        if(i==1&&j==1)continue;
                        if(f[k-a[i][j]][i-1][j]!=-1)
                            f[k][i][j]=f[k-a[i][j]][i-1][j]+a[i][j]*a[i][j];
                        if(f[k-a[i][j]][i][j-1]!=-1)
                        {
                            if(f[k][i][j]==-1)f[k][i][j]=f[k-a[i][j]][i][j-1]+a[i][j]*a[i][j];
                            else f[k][i][j]=min(f[k][i][j],f[k-a[i][j]][i][j-1]+a[i][j]*a[i][j]);
                        }       
    
                    }
            int ans=2000000000;
            for(int i=0;i<=1500;i++)
            {
                if(f[i][n][m]==-1)continue;
                ans=min(ans,f[i][n][m]*g-i*i);
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    轻量级通用上采样算子-CARAFE
    图像分割-Mask Scoring R-CNN
    对C#Chart控件使用整理
    C#中的三种timer
    C#的三大难点
    将Excel的数据导入DataGridView中(转)
    状态者设计模式
    C# 中 DataTable 使用详解。
    Excel连接字符串在.NET中的应用
    状态机设计思想
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7652925.html
Copyright © 2011-2022 走看看