区间DP Halloween Costumes LightOJ - 1422
Posted Vincent_0000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间DP Halloween Costumes LightOJ - 1422相关的知识,希望对你有一定的参考价值。
题目来源
反思
这个题目没有做出来的主要原因是因为找不到他们之间的转换关系,不知道为什么要使用区间DP去做这个题目。
对于里面深层次的含义还没有提炼出来。
以后要根据题意多去提炼一些有用的信息,想到什么有用的就写上。
题解
- 题目分析
求最小值, 数据范围很小,那么盲猜使用DP。
尝试使用DP解题。
- DP 类型分析
我们要结合动态规划的特性去想集合。
我们想出来的集合要能够进行状态与状态之间的转换,这个就需要我们不断的挖崛题目之中的深层含义。
我们观察到:只有表面衣服到要表现出的衣服之间的衣服会受到影响,再往里面的衣服是不受到影响的。
根据这个特性,我们就可以往区间DP的方向去想,使用区间一步一步的迭代出答案。
尝试使用区间DP的解题思路去做题。
- 集合表示
集合表示为
(
l
,
r
)
(l ,r)
(l,r)区间中,穿的衣服数量。
属性为MIN
- 区间DP状态转移方程
其余时候为
f
(
l
,
r
)
=
f
(
l
,
r
−
1
)
+
1
f(l, r) = f(l, r - 1) + 1
f(l,r)=f(l,r−1)+1
当
a
k
=
a
r
a_k = a_r
ak=ar的时候,
f
(
l
,
r
)
=
m
i
n
(
f
(
l
,
r
)
,
f
(
l
,
k
)
+
f
(
k
+
1
,
r
−
1
)
)
f(l, r) = min (f(l, r), f(l, k) + f(k + 1, r - 1) )
f(l,r)=min(f(l,r),f(l,k)+f(k+1,r−1))。
- 边界值分析
当区间长度为1的时候,集合所代表的值一定为1.
- 目标
f ( 1 , n ) f(1, n) f(1,n)
AC代码
#include<bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define For(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(a) cout << #a << " = " << a << endl
#define mod(x) (x) % MOD
#define ENDL "\\n"
#define x first
#define y second
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N = 100 + 7, MOD = 1e9, INF = 0x3f3f3f3f;
int f[N][N], a[N];
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cout.tie(0), cin.tie(0);
int T;
cin >> T;
_rep(kase, 1, T){
int n;
cin >> n;
_rep(i, 1, n) cin >> a[i], f[i][i] = 1;
_rep(len, 1, n) _rep(l, 1, n - len + 1) {
int r = l + len - 1;
f[l][r] = f[l][r - 1] + 1;
_for(k, l, r) if (a[k] == a[r]) f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r - 1]);
}
printf("Case %d: %d\\n", kase, f[1][n]);
}
return 0;
}
以上是关于区间DP Halloween Costumes LightOJ - 1422的主要内容,如果未能解决你的问题,请参考以下文章
LightOJ - 1422 Halloween Costumes(区间dp)
LightOJ 1422Halloween Costumes(区间DP)
LightOJ - 1422 Halloween Costumes (区间DP)
lightoj 1422 Halloween Costumes 区间DP