给你 n 天需要穿的⾐服的样式,每次可以套着穿⾐服,脱掉的⾐服就不能再⽤了(可以再穿),问⾄少要带多少条⾐服才能参加所有宴会
这个题真的真的真的思考了挺长时间才勉强理解才能勉强,感觉和区间dp,,,
状态dp[i][j]dp[i][j] 表示i−ji−j之间需要的衣服数
考虑两种状态:
arr[i]==arr[j]arr[i]==arr[j] 说明和前一个状态衣服件数一样即可 dp[i][j]=dp[i][j−1]dp[i][j]=dp[i][j−1]
分段进行枚举
如果arr[i]=arr[k]arr[i]=arr[k], 这个段的开始点和kk点衣服相同 考虑状态转移
#include <bits/stdc++.h>
using namespace std;
#define CLR(a,b) memset(a, (b), sizeof(a))
const int MAXN = 2e2+10;
int dp[MAXN][MAXN];
int arr[MAXN];
/*
*/
int main(int argc, char const *argv[])
{
int T, kk=0;
scanf("%d",&T);
while(T--) {
int n;
cin >> n;
CLR(dp, 0x3f3f);
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
dp[i][i] = 1;
}
for (int len = 1; len < n; ++len) {
for(int i = 1; i <= n; ++i) {
int j = len+i;
if(j > n) break;
if(arr[i] == arr[j])
dp[i][j] = dp[i][j-1];
for(int k = i; k < j; ++k) {
if(arr[i] == arr[k])
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]);
}
}
}
cout << "Case " << ++kk << ": " << dp[1][n] << endl;
}
return 0;