中午被毛毛虫蛰了一下,现在右手只剩食指和中指能打字了,好不爽。
对于这题,我是先把套娃们分成几组,每组套成一个。计算时枚举分组方式,并从左往右贪心得到每组并成一个套娃的操作数(是的,就是贪心,虽然这是一道DP题)
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
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;
vector<pair<int,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;k<b[i].size();++k)up(f[i],f[b[i][k].first+1]+b[i][k].second);
if(f[1]==inf)puts("impossible");
else printf("%d\n",f[1]);
}
return 0;
}