1222分割字串
阿新 • • 發佈:2020-09-16
我們定義 \(dp_i\) 為前 \(i\) 個字元最長分割的數量,我們發現 \(dp_i\) 可以從 \(dp_j\) \((0\leq j < i)\) 轉移過來,並且發現使得 \(j\) 儘可能大,可以使得往後的轉移條件更容易到達(不會表述)
所以我們只需要 \(n^2\) 就可以辣!
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int read() { int a = 0,x = 1; char ch = getchar(); while(ch > '9' || ch < '0'){ if(ch == '-') x = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ a = a*10 + ch-'0'; ch = getchar(); } return a*x; } const int N=6e2+7; char s[N]; int dp[N],n; int sum[N][30]; int f[N][30]; int main() { // freopen("in.in","r",stdin); // freopen("out.out","w",stdout); scanf("%s",s+1); n = strlen(s+1); for(int i = 1;i <= n;i ++){ for(int j = 0;j < 26;j ++){ sum[i][j] = sum[i-1][j]+(s[i]-'A'==j); } } for(int i = 1;i <= n;i ++){ for(int j = i-1;j >= 0;j --){ bool flag = 0; for(int k = 0;k < 26;k ++){ if(sum[i][k]-sum[j][k] < f[j][k]) flag = 1; } if(flag) continue; dp[i] = dp[j]+1; // printf("%d -> %d\n",j,i); for(int k = 0;k < 26;k ++){ f[i][k] = sum[i][k]-sum[j][k]; } break; } } printf("%d",dp[n]); return 0; }