題目大意:
輸入:
輸出:
樣例輸入:
2 2
2 6
6 3
樣例輸出:
分析:
#include<cstdio>
#define MAXN 1000
using namespace std;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
int n,t,k;
int maxl=1;
int sum[MAXN+5][MAXN+5];
int main()
{
int i,j,x,y;
scanf("%d%d",&n,&t);
for(i=1;i<=t;i++)
{
scanf("%d%d",&x,&y);
sum[x][y]=1;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
for(i=2;i<=n;i++)
for(j=2;j<=n;j++)
{
for(k=maxl;k<min(i,j);k++)
if(sum[i][j]-sum[i-k-1][j]-sum[i][j-k-1]+sum[i-k-1][j-k-1]>0)
break;
maxl=max(k,maxl);
}
printf("%d\n",maxl);
}
下面的是DP正解,狀態轉移方程爲f[i][j]=min(f[i-1][j],f[i][j-1],f[i-1][j-1])+1。f[i][j]表示以(i,j)爲右下角時能達到的最大邊長,比我的區間前綴和簡單多了:#include<cstdio>
#define MAXN 1000
using namespace std;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
int n,t,maxl;
bool field[MAXN+5][MAXN+5];
int f[MAXN+5][MAXN+5];
int main()
{
int i,j,x,y;
scanf("%d%d",&n,&t);
for(i=1;i<=t;i++)
{
scanf("%d%d",&x,&y);
field[x][y]=true;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(field[i][j])
f[i][j]=0;
else
{
f[i][j]=min(f[i-1][j],f[i][j-1]);
f[i][j]=min(f[i][j],f[i-1][j-1])+1;
}
maxl=max(f[i][j],maxl);
}
printf("%d\n",maxl);
}