Lightoj Halloween Costumes

题意:给出要n个时间穿的服装。服装脱下就不能再穿。问最少要准备多少?

dp[i][j]表示i到j之间最少花费。如果n=1(n指长度),肯定结果为1,n=2时,也很好算。然后n=3的时候dp[i][j],到前面找和它相同的k,因为只有和它相同的才能在n=3的时候利用上。dp[i][k]的结果k肯定在最外层,不脱掉它,在dp[k+1][j-1]就套在第k件外边,第j时刻,将[k+1,j-1]脱掉。或者dp[i][j]在dp[i][j-1]的基础上加一件,要么利用原来的一件。利用原先的一件只能在某个第k时刻不脱掉它,在它的外层套。

#pragma comment(linker,"/STACK:1024000000,1024000000") 
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include <stack>
using namespace std;
const int SZ=1e2+20,INF=0x7FFFFFFF;
typedef long long lon;
int n,arr[SZ],res[SZ][SZ];

void init()
{
    cin>>n;
    for(int i=1;i<=n;++i)cin>>arr[i];
    for(int len=1;len<=n;++len)
    {
        for(int i=1;i+len-1<=n;++i)
        {
            int r=i+len-1;
            res[i][r]=res[i][r-1]+1;
            for(int j=i;j<r;++j)
            {
                if(arr[r]==arr[j])res[i][r]=min(res[i][r],res[i][j]+res[j+1][r-1]);
            }
        }
    }
    cout<<res[1][n]<<endl;
}

int main()
{
    std::ios::sync_with_stdio(0);
    int casenum;
    cin>>casenum;
    for(int time=1;time<=casenum;++time)
    {
        cout<<"Case "<<time<<": ";
        init();
    }
    return 0;
}

 

posted @ 2018-10-04 10:46  degvx  阅读(127)  评论(0)    收藏  举报