Light OJ 1422 Halloween Costumes(区间DP)

来源:互联网 发布:linux vi 删除多行 编辑:程序博客网 时间:2024/05/27 19:27

http://lightoj.com/volume_showproblem.php?problem=1422.

题意:给你n天需要穿的衣服的样式,每次可以套着穿衣服,脱掉的衣服就不能再用了(可以再穿),问至少要带多少条衣服才能参加所有宴会。

 dp[i][j]表示i到j区间的最小穿衣数量。然后我们通过扫描i到j之间的k点来更新dp[i][j]。当c[k]与c[j]为相同衣服时,那么显然有dp[i][j] = min(dp[i][j], dp[i][k-1] + dp[k][j-1]),这是因为我们只需要脱掉k+1到j-1,就可以得到c[k](c[j])。dp[i][j]初始化为dp[i][j-1] + 1,因为这是不考虑脱衣服,直接穿新衣服的值。对于dp[i][i],显然为1。

其次就是注意区间扫描时的顺序了。

#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cstdio>#include <vector>#include <string>#include <queue>#include <stack>#include <cmath>#include <set>#include <map>using namespace std;typedef long long LL;#define mem(a, n) memset(a, n, sizeof(a))#define ALL(v) v.begin(), v.end()#define si(a) scanf("%d", &a)#define pb push_back#define eps 1e-8const int inf = 0x3f3f3f3f, N = 1e2 + 5, MOD = 1e9 + 7;int T, cas = 0;int n, m;int dp[N][N], c[N];int main(){#ifdef LOCAL    freopen("/Users/apple/input.txt", "r", stdin);//freopen("/Users/apple/out.txt", "w", stdout);#endif    si(T);    while(T --) {    si(n);    for(int i = 0; i < n; i ++) si(c[i]);    mem(dp, 0);    for(int i = 0; i < n; i ++) dp[i][i] = 1;    for(int j = 1; j < n; j ++) {    for(int i = j - 1; i >= 0; i --) {    dp[i][j] = dp[i][j-1] + 1;    for(int k = j - 1; k >= i; k --) {    if(c[k] == c[j]) dp[i][j] = min(dp[i][j], dp[i][k-1] + dp[k][j-1]);    }    }    }        printf("Case %d: %d\n", ++ cas, dp[0][n - 1]);    }        return 0;}


0 0
原创粉丝点击