Approach
Depth-first search
For CCC 2016 S4 - Combining Riceballs, the implementation follows one branch at a time, making it suitable for components, trees, backtracking, or dependency exploration.
- Define the state carried into one recursive or stack frame.
- Mark or choose the current state before exploring children.
- Combine child results or undo the choice when the branch finishes.
Code notes
- 130 lines of C++ from the credited upstream file ccc16s4.cpp.
- The implementation visibly relies on cached states.
- 7 loop blocks detected.
Complexity
Count unique states for graph traversal; for backtracking, count the branching factor and maximum depth.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1/*2 3CCC '16 S4 - Combining Riceballs4 5Dan Shan, Oakville Trafalgar High School6 7Date: 2025-06-138 9Recursive Dynamic Programming10 11Observation: order of merging doesn't effect the sum12 131. Prefix sum array for O(1) range sum queries.14 152. 2D memoization array stores whether each interval [l, r] is valid (can be merged).16 173. Recursively try to split into 3 parts: left, right, middle (possibly empty).18 194. Optimize Each call from O(N^2) to O(N) through two-pointers technique (Optional but speeds up code significantly)20 215. If left and right have equal sums, and all 3 parts are valid, then dp[l][r] is valid.22 23Time Complexity: O(N^3)24 25 26 27C/C++ implementation28 29*/30 31 32 33#include <stdio.h>34 35#pragma GCC optimize ("Ofast")36 37#define bs 1<<24 // Templates38 39char buf[bs];40 41char *ptr = buf;42 43void buff(){44 45 fread(buf,1,bs,stdin);46 47}48 49long long scan(){ 50 51 long long num=0,neg=1;52 53 while((*ptr<'0'||*ptr>'9')&&*ptr!='-')++ptr; 54 55 while(*ptr=='-')++ptr,neg*=-1;56 57 while(*ptr>='0'&&*ptr<='9') {58 59 num=num*10+(*ptr-'0');60 61 ++ptr;62 63 }64 65 return num*neg;66 67}68 69int dp[401][401],p[401];70 71int solve(int l, int r){72 73 if(dp[l][r]) return dp[l][r];74 75 if(l>=r) return dp[l][r]=1;76 77 int i=l,j=r;78 79 while(i<=j){80 81 int li=p[i]-p[l-1],ri=p[r]-p[j-1];82 83 if(li!=ri){ 84 85 if(li<ri) ++i;86 87 else --j;88 89 continue;90 91 }92 93 if(solve(l,i)>0&&solve(i+1,j-1)>0&&solve(j,r)>0) return dp[l][r]=1;94 95 ++i; --j;96 97 }98 99 return dp[l][r]=-1;100 101}102 103int main(){104 105 buff();106 107 int n=scan(),m=1; p[0]=0;108 109 for(int i=1;i<=n;++i) {110 111 p[i]=scan(); p[i]+=p[i-1];112 113 }114 115 for(int i=1;i<=n;++i){116 117 for(int j=i;j<=n;++j){118 119 int d=p[j]-p[i-1];120 121 if(d>m&&solve(i,j)>0) m=d;122 123 }124 125 }126 127 printf("%d\n",m);128 129}130