luogu1115: 최대 하위 세그먼트와: 욕심/2점+귀속

제목 연결

  • 이 문제는 루거 시련장의 2-13:T2
  • 제목의 대의.

  • n개의 숫자, 구자단 중 가장 큰 연속화;

  • 제목 분석

  • 제목을 보면 첫 번째 반응은 대열:
  • 그러나 자단의 길이를 모르기 때문에 언제 대열이 나올지 판단하기 어렵다.
  • 사고방식1: 욕심
  • 사고방식 2: 라인 트리식의 귀속
  • 탐욕

  • 현재 i를 설정하면 앞의'세그먼트'와 마이너스가 될 수 없습니다.
  • 그래서 앞의'단'과 마이너스가 아니면 i를 추가할 수 있다.
  • 만약에 앞의'세그먼트'의 합이 마이너스라면 i는 다시 세그먼트를 엽니다.

  • 욕심 코드:


    비교적 짧고 이해가 관건이다
    //luogu1115:  
    
    //  
     
    #include
    using namespace std;
     
    int n,x,s=0,ans;
      
    int main()
    {
    	scanf("%d",&n);
    	
    	scanf("%d",&x);//  
    	s=x; 
    	ans=x;
    	if(s<0) s=0;	
    	
    	for(int i=2;i<=n;i++)
    	{
    		scanf("%d",&x);
    		
    		s+=x;//  
    		if(ans

    사고방식 2: 라인 트리식의 귀속

  • 요구에 부합되는 단락은 [x,y]이다.
  • 이 섹션은 다음과 같습니다.
  • L <= x < y <= mid ;
  • mid < x < y <= R ;
  • L <= x < mid < y <= R ;
  • 그래서 끊임없이 2점을 나누어 거슬러 올라갈 때 해답을 구한다.
  • 주의: [x,y]는 연속적이므로 반드시mid에서 양쪽으로 화합을 구해야 합니다!

  • 코드 2: 유사한 세그먼트 트리의 이분 귀속

  • 거슬러 올라가는 내용을 철저히 이해해야 진정한 이해가 귀착된다
  • //luogu1115:  
    
    //  
    //  
     
    #include
    using namespace std;
     
    const int mx=2e5+5,mi=-2e5+5;
    int a[mx],n;
    
    int dfs(int l,int r)
    {
    	if(l==r) return a[l]; // 
    	
    	int mid=(l+r)/2,s1=mi,s2=mi;
    	
    	int s=0;
    	for(int i=mid;i>=l;i--)// :  
    	{
    		s+=a[i];
    		s1=max(s1,s);
    	}
    	
    	s=0;
    	for(int i=mid+1;i<=r;i++)// : 
    	{
    		s+=a[i];
    		s2=max(s2,s);
    	}
    	
    	return max(max(dfs(l,mid),dfs(mid+1,r)),s1+s2);
    }
    
    int main()
    {
    	scanf("%d",&n);
    	
    	for(int i=1;i<=n;i++) 
    	{
    		scanf("%d",&a[i]);
    	}
    	
    	int ans=dfs(1,n);
    	
    	printf("%d",ans);
    
    	return 0;
    }
    
    

    좋은 웹페이지 즐겨찾기