[POI2006]ORK-Ploughing

Posted faced

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2006]ORK-Ploughing相关的知识,希望对你有一定的参考价值。

[POI2006]ORK-Ploughinghttps://www.luogu.org/problemnew/show/P3444

题目描述

\(Byteasar\) 想耕种他那块矩形的田,他每次能耕种矩形的一边(上下左右都行), 在他每次耕完后,剩下的田也一定是矩形,每块小区域边长为 \(1\),耕地的长宽分 别为 \(m\)\(n\),不幸的是 \(Byteasar\) 只有一匹老弱的马,从马开始耕地开始,只有当 它耕完了一边才会停下休息。但有些地会非常难耕以至于马会非常的累,因此 \(Byteasar\) 需要特别小心。当耕完了一边之后,马可以停下来休息恢复体力。每块 地耕种的难度不一,但是 \(Byteasar\) 都非常清楚。我们将地分成 \(m*n\) 块单位矩形 ——我们用坐标\((I,j)\)来定义它们。每块地都有一个整数 \(T[I,J]\),来定义\((I,j)\)的耕 种难度。所以每次马耕一边地时的难度就是所有它耕种的地的难度总和,对于这 匹虚弱的马而言,这个值不能超过他的体力值。\(Byteasar\) 想知道在马不死掉的情 况下最少需要耕多少次才能把地耕完。

输入格式:

第一行三个整数, \(K,M,N\)\(1<=k<=200 000 000\),\(1<=m,n<=2000\).其中 \(K\) 表示马的体力 值。 接下来 \(N\) 行每行 \(M\) 个整数表示难度值。\((0<=\)难度值\(<=10 000)\)

输出格式:

一个整数表示最少的耕种次数(保证马能耕完)。

输入样例:

12 6 4
6 0 4 8 0 5
0 4 5 4 6 0
0 5 6 5 6 0
5 4 0 0 5 4

输出样例:

8


贪心:
最少次数:\(min(n,m)\):直接只横切或只纵切切完
最多次数:\(n+m\):既横切又纵切
贪心策略:先优先横切,枚举切左边的次数\([1,m]\),尽可能少切右边
再优先纵切,枚举切上面的次数\([1,n]\),尽可能少切下边
所有次数取\(min\)即可

前缀和优化查询O(1)
存在无解的情况返回inf
#define RG register
#include<iostream>
#include<cstdio>
using namespace std;
const int N=2005;
inline int read()
{
    RG int x=0,w=1;RG char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
    return x*w;
}
int k,m,n,Ans=1e9;
int a[N][N],r[N][N],l[N][N];
inline int del1(int lim,int L,int R,int U,int D)
{
    int Sum=0;
    while(L<=R&&U<=D)
    {
        Sum++;
        if(l[D][L]-l[U-1][L]<=k){L++;continue;}
        if(l[D][R]-l[U-1][R]<=k){R--;continue;}
        if((r[U][R]-r[U][L-1]<=k)&&(U<=lim)){U++;continue;}
        if(r[D][R]-r[D][L-1]<=k)D--;
        else return 1e9;
    }
    return Sum;
}
inline int del2(int lim,int L,int R,int U,int D)
{
    int Sum=0;
    while(L<=R&&U<=D)
    {
        Sum++;
        if(r[U][R]-r[U][L-1]<=k){U++;continue;}
        if(r[D][R]-r[D][L-1]<=k){D--;continue;}
        if((l[D][L]-l[U-1][L]<=k)&&(L<=lim)){L++;continue;}
        if(l[D][R]-l[U-1][R]<=k)R--;
        else return 1e9;
    }
    return Sum;
}
int main()
{
    k=read();
    m=read();
    n=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            a[i][j]=read();
            r[i][j]=r[i][j-1]+a[i][j];
            l[i][j]=l[i-1][j]+a[i][j];
        }
    for(int i=0;i<n;i++)Ans=min(Ans,del1(i,1,m,1,n));
    for(int i=0;i<m;i++)Ans=min(Ans,del2(i,1,m,1,n));
    printf("%d\n",Ans);
    return 0;
}

以上是关于[POI2006]ORK-Ploughing的主要内容,如果未能解决你的问题,请参考以下文章

[POI2006]ORK-Ploughing

bzoj1510[POI2006]Kra-The Disks*

[POI2006]MET-Subway - 解题报告

[POI2006]TET-Tetris 3D

1512: [POI2006]Pro-Professor Szu

阅读Microsoft Word文档时出现Android Apache POI错误:org.apache.xmlbeans.SchemaTypeLoaderException无法解析句柄的类型(代码片