https://leetcode-cn.com/problems/strange-printer/
思路:dp还是不太熟悉呀……考虑用
d
p
i
,
j
dp_{i,j}
dpi,j表示打印区间
[
i
,
j
]
[i,j]
[i,j]所需要的最少次数,那么显然
d
p
i
,
i
=
1
dp_{i,i}=1
dpi,i=1,对于区间
[
i
,
j
]
[i,j]
[i,j],枚举断点
k
k
k,有
d
p
i
,
j
=
m
i
n
(
d
p
i
,
k
+
d
p
k
+
1
,
j
)
dp_{i,j}=min(dp_{i,k}+dp_{k+1,j})
dpi,j=min(dpi,k+dpk+1,j),需要注意的特殊情况是
s
i
=
s
j
s_i=s_j
si=sj时,我们可以在打印字符
s
i
s_i
si时同时打印字符
s
j
s_j
sj,相当于通过一次操作把
[
i
,
j
]
[i,j]
[i,j]全部打印为
s
i
s_i
si,没有使用额外操作,因此有
d
p
i
,
j
=
d
p
i
,
j
−
1
dp_{i,j}=dp_{i,j-1}
dpi,j=dpi,j−1。
class Solution {
public:
int strangePrinter(string s) {
int n=s.size();
vector<vector<int>> dp(n,vector<int>(n));
for(int i=0;i<n;i++)
dp[i][i]=1;
for(int len=2;len<=n;len++)
{
for(int i=0;i+len-1<n;i++)
{
int j=i+len-1;
if(s[i]==s[j])
dp[i][j]=dp[i][j-1];
else
{
int MIN=0x3f3f3f3f;
for(int k=i;k<j;k++)
MIN=min(MIN,dp[i][k]+dp[k+1][j]);
dp[i][j]=MIN;
}
}
}
return dp[0][n-1];
}
};