这题卡时间很紧,首先肯定是要去重的,还要离散化一下,但是用map离散都不行,可能是最坏情况过不了。
后来用数组来完成离散化。但是C++TLE到死,后来用G++竟然A了,不到1s,我也是醉了~
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define MAX 51111
int a[MAX],b[MAX],vis[MAX],dp[MAX];
int n;
vector<int> v;
int read()
{
int ans = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans;
}
int main()
{
int i,j,k;
int cnt;
int bnum;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
//scanf("%d",&a[i]);
a[i]=read();
b[i]=a[i];
vis[i]=0;
dp[i]=1<<30;
}
a[n+1]=b[n+1]=0;
sort(b+1,b+n+1);
bnum=0;
cnt=0;
for(i=2;i<=n+1;i++)
{
if(a[i-1]!=a[i])
{
cnt++;
a[cnt]=a[i-1];
}
if(b[i-1]!=b[i])
{
bnum++;
b[bnum]=b[i-1];
}
}
for(i=1;i<=cnt;i++)
{
int pos=lower_bound(b+1,b+bnum+1,a[i])-b;
a[i]=pos;
}
dp[0]=0;
dp[cnt]=cnt;
for(i=0;i<=cnt;i++)
{
k=0;
if(dp[i]>=dp[i+1]) continue;
for(j=i+1;j<=cnt;j++)
{
if(vis[a[j]]==0)
{
k++;
vis[a[j]]=1;
v.push_back(a[j]);
}
if(dp[i]+k*k>=dp[cnt]) break;
dp[j]=min(dp[j],dp[i]+k*k);
}
for(int temp=0;temp<v.size();temp++)
vis[v[temp]]=0;
v.clear();
}
printf("%d\n",dp[cnt]);
}
return 0;
}