DP 매일 3마리
6488 단어 dp
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#define Rep(i,n) for(int i = 1; i <= n ; i ++)
#define RepG(i,x) for(int i = head[x] ;~ i ; i = edge[i].next)
#define Rep_d(i,n) for(int i = n ; i > 0 ; i --)
#define Rep_0(i,n) for(int i = 0 ; i < n ; i ++)
#define RD(i,x,n) for(int i = x; i <= n ; i ++)
#define CLR(a,b) memset(a,b,sizeof(a))
#define v edge[i].to
using namespace std;
const int inf = 1 << 30; int read(){ char ch = getchar(); while(ch < '0' || ch > '9')ch = getchar ();
int x = 0;
while(ch >= '0' && ch <= '9')x = 10 * x + ch - '0',ch = getchar ();
return x;
}
int f[1005][1005];
bool w[1005][1005];
int up[1005][1005],lft[1005][1005];
int main()
{
int n = read(),m = read();
Rep(i,n)
Rep(j,m){
w[i][j] = read();
if(w[i][j])lft[i][j] = lft[i][j - 1] + 1;
else lft[i][j] = 0;
}
Rep(i,m)
Rep(j,n){
if(w[j][i])up[j][i] = up[j - 1][i] + 1;
else up[j][i] = 0;
}
/* Rep(i,n)
Rep(j,m)
printf("(%d,%d) %d %d
",i,j,up[i][j],lft[i][j]);*/
CLR(f,127);
f[1][1] = w[1][1];
int ans = 0;
Rep(i,n)
Rep(j,m){
if(w[i][j]){
f[i][j] = min(f[i - 1][j - 1] + 1,min(up[i][j],lft[i][j]));
ans = max(ans,f[i][j]);
}
else f[i][j] = 0;
}
printf("%d
",ans);
return 0;
}
그래서 세 번째 문제는 물문제를 풀기로 했다. 서열 A = "a1 to an", 정의 d (A) = (http://pic002.cnblogs.com/images/2012/305173/2012062923105331.png); d (A) 구하기;즉, 최대 2개의 연속 필드 및
#include <cstdio>
#include <algorithm>
#include <cstring>
#define CLR(a,b) memset(a,b,sizeof(a))
#define Rep(i,n) for(int i = 1 ; i <= n ; i ++)
#define RepG(i,x) for(int i = head[x]; ~ i ; i = edge[i].next)
#define Rep_0(i,n) for(int i = 0 ; i < n ; i ++)
#define Rep_d(i,n) for(int i = n; i >= 1; i --)
#define u t[x]
#define o t[y]
#define lc ch[0]
#define rc ch[1]
#define lson u.lc,l,mid
#define rson u.rc,mid + 1,r
#define N 50005
int l[N],r[N],a[N],n,lMax[N],rMax[N];
int main (){
int cases;
scanf("%d",&cases);
while(cases --){
CLR(lMax,-127),CLR(rMax,-127);
scanf("%d",&n);
Rep(i,n)
scanf("%d",&a[i]);
Rep(i,n)
l[i] = std :: max(l[i - 1] + a[i],a[i]);
Rep_d(i,n)
r[i] = std :: max(r[i + 1] + a[i],a[i]);
Rep(i,n)
lMax[i] = std :: max(lMax[i - 1],l[i]);
Rep_d(i,n)
rMax[i] = std :: max(rMax[i + 1],r[i]);
int Maxn = - (1 << 30);
Rep(i,n)
Maxn = std :: max(Maxn,lMax[i] + rMax[i + 1]);
printf("%d
",Maxn);
}
return 0;
}
대개 x를 경계점으로 하는 좌우 양쪽에서 얻을 수 있는 최대치를 계산해 낸다.