b_lg_塗色(從小區間做起,討論s[l]和s[r]的關係)
阿新 • • 發佈:2020-09-15
每次你可以把一段連續的木版塗成一個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成 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)\),