f[i][j][2]表示前i個數以j個數結尾,0是低穀,1是高峰
轉移方程:f[i][j][0] = max(f[i][j][0], f[i-j][k][1] + 1);
f[i][j][1] = max(f[i][j][1], f[i-j][k][0] + 1);
#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN INT_MIN#define MAX INT_MAX#define PI acos(-1.0)#define FRE freopen("input.txt","r",stdin)#define FF freopen("output.txt","w",stdout)#define N 105int max(int x,int y){return x > y ? x : y;}char str[N];int a[N];int n;int f[N][N][2];int chk (int l1,int r1,int l2,int r2) { while (l1 <= r1 && a[l1] == 0) l1++; while (l2 <= r2 && a[l2] == 0) l2++; int l = r1 - l1 + 1; int r = r2 - l2 + 1; if (l < r) return -1; if (l > r) return 1; for (int i = l1 ,j = l2; i <= r1; i++, j++) { if (a[i] > a[j]) return 1; if (a[i] < a[j]) return -1; } return 0;}int main () { while (scanf("%d%s",&n,str) != EOF) { int i,j,k; for (i = 0; i < n ; i++) a[i+1] = str[i] - '0'; memset(f,-1,sizeof(f)); f[1][1][0] = 0; for (i = 2 ; i <= n ; i++) { f[i][i][0] = 1; for (j = 1 ; j < i; j++) { for (k = 1; k <= i - j; k++) { if (chk(i-j-k+1, i-j, i-j+1, i) > 0) { if (f[i-j][k][1] == -1) continue; f[i][j][0] = max(f[i][j][0], f[i-j][k][1] + 1); } if (chk(i-j-k+1, i-j, i-j+1, i) < 0) { if (f[i-j][k][0] == -1) continue; f[i][j][1] = max(f[i][j][1], f[i-j][k][0] + 1); } } } } int ans = 0; for (i = 1; i <= n; i++) { //cout<<f[n][i][0]<<" "<<f[n][i][1]<<endl; ans = max(ans, f[n][i][0]); ans = max(ans, f[n][i][1]); } printf("%d\n",ans); } return 0;}