zoukankan      html  css  js  c++  java
  • P2216 [HAOI2007]理想的正方形

    博客食用效果更佳

    题目描述

    给定一个(n imes m)的矩阵,对于每个$k imes k $的矩形,其权值为最大值减去最小值

    求最小权值

    (n,mleq 100)

    题解

    滑动窗口的二维版

    于是思路是优先队列优化dp

    其实二维ST表也不是不行 但是卡在复杂度上界

    想起当年静态二维RMQ写了2k树套树 一上午看到代码就想吐

    我们可以一步步来,先对于每一行求出每个数前k个数字的最大最小值

    然后以此类推求出每个矩形的最大最小值

    虽然复杂度看起来是n方,但STL还是慢的离谱,不开O2甚至能T一个点

    下次手写单调队列了/kk

    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=0x7fffffff;
    typedef long long ll;
    #define maxn 1009
    int n,m;
    int k;
    int a[maxn][maxn];
    int f[maxn][maxn],g[maxn][maxn],ff[maxn][maxn],gg[maxn][maxn]; 
    signed main()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			scanf("%d",&a[i][j]);
    		}
    	}
    	for(int j=1;j<=n;j++)
    	{
    		priority_queue<pair<int,int> > q2; 
    		priority_queue<pair<int,int> ,vector<pair<int,int> > ,greater<pair<int,int> > > q;
    		for(int i=1;i<=m;i++)
    		{
    			while(!q.empty()&&i-q.top().second>=k)q.pop();
    			while(!q2.empty()&&i-q2.top().second>=k)q2.pop(); 
    			q.push(make_pair(a[j][i],i));
    			q2.push(make_pair(a[j][i],i));
    			f[j][i]=q.top().first;
    			g[j][i]=q2.top().first;
    		}
    	}
    	for(int i=1;i<=m;i++)
    	{
    		priority_queue<pair<int,int> > q2;
    		priority_queue<pair<int,int> ,vector<pair<int,int> > ,greater<pair<int,int> > > q;
    		for(int j=1;j<=n;j++)
    		{
    			while(!q.empty()&&j-q.top().second>=k)q.pop();
    			while(!q2.empty()&&j-q2.top().second>=k)q2.pop(); 
    			q.push((make_pair(f[j][i],j)));
    			q2.push((make_pair(g[j][i],j)));
    			ff[j][i]=q.top().first;
    			gg[j][i]=q2.top().first;
    		}
    	}
    	int ans=inf;
    	for(int i=k;i<=n;i++)
    	{
    		for(int j=k;j<=m;j++)
    		{
    			ans=min(gg[i][j]-ff[i][j],ans);
    			//cout<<i<<" "<<j<<" max:"<<gg[i][j]<<" min:"<<ff[i][j] <<endl;
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    /*
    f[i]表示i点往左n个数字的最小值 
    g[i]表示                最大值 
    ff[i][j]表示i,j为右下角的矩阵最小值 
    gg[i][j]表示          最大值 
    */
    
  • 相关阅读:
    软件工程实验二
    软件工程实验一
    软件工程作业--ATM自助银行服务系统
    软件工程作业—举例分析流程图与活动图的区别与联系
    第一个随笔
    机器学习 实验四 决策树算法及应用
    机器学习实验三 朴素贝叶斯算法及应用
    机器学习 实验二 K-近邻算法及应用
    飞机订票系统(文档)
    机器学习 实验一 感知器及其应用
  • 原文地址:https://www.cnblogs.com/lzy-blog/p/15158460.html
Copyright © 2011-2022 走看看