2020牛客暑假多校训练营(第二场)F-Fake Maxpooling(DP)

地址:https://ac.nowcoder.com/acm/contest/5667/F

 

题意:

n*m的矩阵,mp[i][j]=lcm(i,j)

求每个k*k矩阵的最大值之和

解析一,DP做法:

针对k>1的情况,我们把每个2*2矩阵的最大值放在右下角。

k*k的矩阵,它是由若干个2*2的矩阵组成。

mp[i][j]=max(mp[i][j],max(mp[i-1][j],mp[i][j-1]));

这样,每个k*k矩阵,它的最大值都在右下角。

求(k~m)*(k~n)的矩阵和即可。

#include<cstdio>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include <deque>
typedef long long ll;
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;//ó??è?aD?μ?ó??è?óáD
deque<int> deq;
const int ma=2e2+20;
const int maxn=5e3+20;
int mp[maxn][maxn];
int mb[maxn][maxn];
int pos[ma];
int top=0;
int ok=0;
int n,m,k;
struct node
{
    int x,id;
}st[maxn];
bool cmp(node a , node b)
{
    if(a.x==b.x)
        return a.id<b.id;
    return a.x<b.x;
}
int getlcm(int a,int b)
{
    return a*b/__gcd(a,b);
}
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{   // 4 0 20
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            mp[i][j]=i*j/gcd(i,j);
        }
    }
    if(k>1)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                mp[i][j]=max(mp[i][j],max(mp[i-1][j],mp[i][j-1]));
        }
                 
    }
    ll sum=0;
    for(int i=k;i<=n;i++)
    {
        for(int j=k;j<=m;j++)
            sum+=mp[i][j];
    }
    cout<<sum<<endl;
}
posted @ 2020-07-16 11:56  liyexin  阅读(192)  评论(0编辑  收藏  举报