UVA1579,俄罗斯套娃

中午被毛毛虫蛰了一下,现在右手只剩食指和中指能打字了,好不爽。
对于这题,我是先把套娃们分成几组,每组套成一个。计算时枚举分组方式,并从左往右贪心得到每组并成一个套娃的操作数(是的,就是贪心,虽然这是一道DP题)

#include 
#include
#include
using namespace __gnu_pbds;
typedef tree<int,null_type,std::less<int>,rb_tree_tag,tree_order_statistics_node_update> SI;
using namespace std;
const int N=510,inf=1<<25;
int f[N],n,i,a[N],j,x;
SI s;
vectorint,int> > b[N];
unsigned int k;
inline void up(int&a,int b){
    if(a>b)a=b;
}
int main(){
    while(scanf("%d",&n)!=EOF){
        f[n+1]=0;
        for(i=1;i<=n;++i)scanf("%d",a+i),f[i]=inf,b[i].clear();
        for(i=1;i<=n;++i){
            s.clear();
            s.insert(a[i]);
            if(a[i]==1)b[i].push_back(make_pair(i,0));
            x=0;
            for(j=i+1;j<=n;++j)
                if(s.find(a[j])==s.end()){
                    x+=s.size()-s.order_of_key(a[j])+(a[j]>*s.begin());
                    s.insert(a[j]);
                    if(*s.begin()==1 && *s.rbegin()==j-i+1 && (int)s.size()==j-i+1)b[i].push_back(make_pair(j,x));
                }else break;
        }
        for(i=n;i;--i)
            for(k=0;k1]+b[i][k].second);
        if(f[1]==inf)puts("impossible");
            else printf("%d\n",f[1]);
    }
    return 0;
}

你可能感兴趣的:(UVA1579,俄罗斯套娃)