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]表示          最大值 
    */
    
  • 相关阅读:
    hdu 4651 Partition (利用五边形定理求解切割数)
    单点登录SSO的实现原理
    高速排序算法
    2014 百度之星第三题
    TR069协议向导——一个帮助你了解TR069协议的简明教程(一)
    教你用笔记本破解无线路由器password
    人脸识别算法初次了解
    JSP验证码
    GROUP BY,WHERE,HAVING之间的差别和使用方法
    typedef函数指针使用方法
  • 原文地址:https://www.cnblogs.com/lzy-blog/p/15158460.html
Copyright © 2011-2022 走看看