Memory search, enumeration of all cutting methods DP[R1][C1][R2][C2] represents (R1, C1) (R2, C2) the minimum cost required for cake cutting count_num used to calculate (R1, C1) (R2, C2) between how many strawberry recursion boundaries when Count_ Num is 1 is return 0
Init () is a pretreatment of the number of strawberries, making it possible to calculate the number of strawberries in the region in the time of O (1)
The total number of states is M * n * M * N decision has n + m species
Time Complexity of O ((n + m) * n * n * m * m)
/*583ms*/
1#include <cstdio>2#include <cmath>3#include <cstring>4#include <algorithm>5#include <map>6#include <Set>7#include <vector>8#include <queue>9#include <iostream>Ten #definePB push_back One #definePOB Pop_back A #definePII Pair<int, int> - #definePDD pair<double, double> - #defineRep (I, A, b) for (int i = A; I < b; i++) the #pragmaComment (linker, "/stack:1024000000,1024000000") - #ifdef WIN32 - #defineINT64 "%i64d" - #defineUINT64 "%i64u" + #else - #defineINT64 "%lld" + #defineUINT64 "%llu" A #endif attypedefLong LongLL; -typedef unsignedLong LongULL; - using namespacestd; - Const intMAXN = A; - Const intINF =0x3f3f3f3f; - intDP[MAXN][MAXN][MAXN][MAXN]; in intCOU[MAXN][MAXN]; - intN, M, K; to voidinit () { + for(inti =1; I <= N; i++) - for(intj =2; J <= M; J + +) theCOU[I][J] + = cou[i][j-1]; * for(inti =2; I <= N; i++) $ for(intj =1; J <= M; J + +)Panax NotoginsengCOU[I][J] + = cou[i-1][j]; - } the intCount_num (intR1,intC1,intR2,intC2) { + intA = COU[R2][C1-1]; A intb = cou[r1-1][C2]; the intc = cou[r1-1][C1-1]; + returnCOU[R2][C2]-A-B +C; - } $ intDP (intR1,intC1,intR2,intC2) { $ int& cnt =DP[R1][C1][R2][C2]; - if(cnt = INF)returnCNT; - if(Count_num (R1, C1, r2, c2) = =1)returnCNT =0; the for(inti = r1; i < R2; i++) {//ºáxåçð - intNUM1 =Count_num (R1, C1, I, C2);Wuyi intnum2 = Count_num (i +1, C1, r2, C2); the if(NUM1 = =0|| Num2 = =0)Continue; -CNT = MIN (CNT, DP (R1, C1, I, C2) + DP (i +1, C1, R2, C2) + C2-C1 +1); Wu } - for(inti = C1; i < C2; i++) { About intNUM1 =Count_num (R1, C1, R2, i); $ intnum2 = Count_num (r1, i +1, r2, C2); - if(NUM1 = =0|| Num2 = =0)Continue; -CNT = MIN (CNT, DP (R1, C1, R2, i) + DP (R1, i +1, r2, C2) + R2-R1 +1); - } A returnCNT; + } the intMain () - { $ intCa1); the while(SCANF ("%d%d%d", &n, &m, &k) = =3) { the if(k = =0) { theprintf"Case %d:%d\n", ca++,0); the } -Memset (DP,0x3f,sizeofDP); inmemset (Cou,0,sizeofcou); the for(inti =0; I < K; i++) { the intx, y; scanf"%d%d", &x, &y); AboutCou[x][y] =1; the } the init (); theprintf"Case %d:%d\n", ca++, DP (1,1, N, m)); + } - return 0; the}
UVA 1629-cake Slicing (memory search)