西安网络预赛题。
连续选区间填充,完全覆盖。
dp[i] 完全覆盖的最优解。
连续一起的同种颜色缩并。
优化:
1. 至多每个单独选,价值最高为N
2.不能连续选择超过sqrt(N)+1个不同的颜色
3.第i种颜色来的时候,它之前本身的颜色不再考虑。
PS:此题本来打算离散化数据,但是用map就不用了(直接判重)。对于有序的数据,离散化还要再映射
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define MAXN (50000+5)
using namespace std;
int a[MAXN],b[MAXN],pre[MAXN],nxt[MAXN];
int dp[MAXN];
int main()
{
int N,M;pre[0]=-1;map<int,int> color;
while(~scanf("%d",&N)){
for(int i=1;i<=N;i++)
scanf("%d",a+i),pre[i]=i-1,nxt[i]=i+1;
M=1;b[1]=a[1];
for(int i=2;i<=N;i++)
if(a[i]!=a[i-1])
b[++M]=a[i];
dp[0]=0;color.clear();
for(int i=1;i<=M;i++){
if(color[b[i]]==0) color[b[i]]=i;//map判重
else{
int k=color[b[i]];
nxt[pre[k]]=nxt[k];
pre[nxt[k]]=pre[k];
color[b[i]]=i;
}
dp[i]=i;
for(int j=i-1,k=1;j!=-1;j=pre[j],k++){
if(k>(int)sqrt(M)+1) break;
int tmp=dp[j]+k*k;
if(tmp>M)break;
dp[i]=min(dp[i],tmp);
}
}
printf("%d\n",dp[M]);
}
}原文:http://blog.csdn.net/gg_gogoing/article/details/41743087