CCC 2016 S4 - Combining Riceballs
← Back to Forum

CCC 2016 S4 - Combining Riceballs

/*

CCC '16 S4 - Combining Riceballs

Dan Shan, Oakville Trafalgar High School

Date: 2025-06-13

Recursive Dynamic Programming

Observation: order of merging doesn't effect the sum

1. Prefix sum array for O(1) range sum queries.

2. 2D memoization array stores whether each interval [l, r] is valid (can be merged).

3. Recursively try to split into 3 parts: left, right, middle (possibly empty).

4. Optimize Each call from O(N^2) to O(N) through two-pointers technique (Optional but speeds up code significantly)

5. If left and right have equal sums, and all 3 parts are valid, then dp[l][r] is valid.

Time Complexity: O(N^3)


C/C++ implementation

*/


#include <stdio.h>

#pragma GCC optimize ("Ofast")

#define bs 1<<24 // Templates

char buf[bs];

char *ptr = buf;

void buff(){

  fread(buf,1,bs,stdin);

}

long long scan(){ // Fast input

  long long num=0,neg=1;

  while((*ptr<'0'||*ptr>'9')&&*ptr!='-')++ptr; // Skip non-digit characters

  while(*ptr=='-')++ptr,neg*=-1;

  while(*ptr>='0'&&*ptr<='9') {

    num=num*10+(*ptr-'0');

    ++ptr;

  }

  return num*neg;

}

int dp[401][401],p[401];

int solve(int l, int r){

  if(dp[l][r]) return dp[l][r];

  if(l>=r) return dp[l][r]=1;

  int i=l,j=r;

  while(i<=j){

    int li=p[i]-p[l-1],ri=p[r]-p[j-1];

    if(li!=ri){ // sums don't match

      if(li<ri) ++i;

      else --j;

      continue;

    }

    if(solve(l,i)>0&&solve(i+1,j-1)>0&&solve(j,r)>0) return dp[l][r]=1;

    ++i; --j;

  }

  return dp[l][r]=-1;

}

int main(){

  buff();

  int n=scan(),m=1; p[0]=0;

  for(int i=1;i<=n;++i) {

    p[i]=scan(); p[i]+=p[i-1];

  }

  for(int i=1;i<=n;++i){

    for(int j=i;j<=n;++j){

      int d=p[j]-p[i-1];

      if(d>m&&solve(i,j)>0) m=d;

    }

  }

  printf("%d\n",m);

}

By Dan-Shan on 6/14/2025
2

Comments