思路
先把所有的答案dp[i][j]初始化为最差的解(因为后面要取min),也就是每件衣服都是新买的衣服(最大的花费)。
对于
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 如果是由之前买新衣服来的,则
d
p
[
i
]
[
j
]
=
d
p
[
i
]
[
j
−
1
]
+
1
dp[i][j] = dp[i][j - 1] + 1
dp[i][j]=dp[i][j−1]+1
然后再考虑在这个区间范围,是否有一天要穿相同的衣服。
对于
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]枚举间断点k,如果衣服的种类
k
i
n
d
[
k
]
=
=
k
i
n
d
[
j
]
kind[k] == kind[j]
kind[k]==kind[j],即如果第 k 天衣服和第 i 天的衣服是一样的,那就比较第 j 天穿一件新的与不穿一件新的衣服。
穿一件新的衣服在进入分割的时候就已经算了,所以我们直接看不穿一件新衣服,取小即可。
d
p
[
i
]
[
j
]
=
d
p
[
i
]
[
k
]
+
d
p
[
k
+
1
]
[
j
−
1
]
dp[i][j] = dp[i][k] + dp[k + 1][j - 1]
dp[i][j]=dp[i][k]+dp[k+1][j−1]
代码
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 1e2 + 10;
int dp[maxn][maxn];
int a[maxn];
int main()
{
int n, T;
scanf("%d", &T);
for(int t = 1; t <= T; t++)
{
memset(dp, 0, sizeof(dp));
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
dp[i][j] = j - i + 1;//初始化最大值,假设我每一件都穿新衣服
for(int len = 1; len <= n; len++)
{
for(int i = 1; i + len <= n; i++)
{
int j = i + len;
dp[i][j] = dp[i][j - 1] + 1;
for(int k = i; k < j; k++)
if(a[k] == a[j])
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j - 1]);
}
}
printf("Case %d: %d\n", t, dp[1][n]);
}
return 0;
}
参考来源
博客
https://blog.csdn.net/qq_34374664/article/details/54867113