b_lg_涂色(从小区间做起,讨论s[l]和s[r]的关系)
每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成 RRRRR,第二次涂成 RGGGR,第三次涂成 RGBGR,达到目标。用尽量少的涂色次数达到目标。
提示:n<50
方法一:dp
题目等价于将目标串变为空串的最小消除次数,比如 xxAAAxx,AAA 可以一次消掉
- 思考状态转移方程:
- f[i][j]=min(f[i+1][j], f[i][j-1]),if (s[i]=s[j]),当他们相等时,涂色的时候可以在涂 s[i,j-1]/s[i+1,j] 时顺便多涂一格
- f[i][j]=min(f[i+1][j], f[i][k]+f[k+1][j]),if (s[i]≠s[j])
#include<bits/stdc++.h>
using namespace std;
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string s; cin>>s;
int n=s.size(), f[n+1][n+1]; memset(f, 0x3f3f3f3f, sizeof f);
for (int i=1; i<=n; i++) f[i][i]=1;
for (int len=2; len<=n; len++)
for (int l=1; l<=n-len+1; l++) {
int r=l+len-1;
if (s[l-1]==s[r-1]) f[l][r]=min(f[l+1][r], f[l][r-1]);
else for (int k=l; k<r; k++) f[l][r]=min(f[l][r], f[l][k]+f[k+1][r]);
}
cout<<f[1][n];
return 0;
}
复杂度分析
- Time:\(O(n^3)\),
- Space:\(O(n^2)\),