Problem Description
Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans to color the pearls to make it more fascinating. He drew his ideal pattern of the string on a paper and asks for your help.
In each operation, he selects some continuous pearls and all these pearls will be painted to their target colors. When he paints a string which has k different target colors, Lee will cost k2 points.
Now, Lee wants to cost as few as possible to get his ideal string. You should tell him the minimal cost.
In each operation, he selects some continuous pearls and all these pearls will be painted to their target colors. When he paints a string which has k different target colors, Lee will cost k2 points.
Now, Lee wants to cost as few as possible to get his ideal string. You should tell him the minimal cost.
Input
There are multiple test cases. Please process till EOF.
For each test case, the first line contains an integer n(1 ≤ n ≤ 5×104), indicating the number of pearls. The second line contains a1,a2,...,an (1 ≤ ai ≤ 109) indicating the target color of each pearl.
For each test case, the first line contains an integer n(1 ≤ n ≤ 5×104), indicating the number of pearls. The second line contains a1,a2,...,an (1 ≤ ai ≤ 109) indicating the target color of each pearl.
Output
For each test case, output the minimal cost in a line.
Sample Input
3
1 3 3
10
3 4 2 4 4 2 4 3 2 2
Sample Output
2
7
Source
题意:一个数列,每个点代表一种颜色,每次选一个区间覆盖,覆盖的代价是区间内颜色种类数的平方,直到覆盖整个数列,求最小花费 思路:1、首先将相邻的两个相同的数合并,记录下它的idd号和数值 2、然后要将的值离散化,因为后面要用到标记数组vis,而a[i]的范围太大(10e9),所以要离散化后才能标记 3、定义一个dp[]数组,dp[i]表示取到i个数时的最小代价,注意dp[tot]=tot,因为最多也就tot,(可以一个一个取)。 4、这边有个剪枝(至关重要,不剪枝会超时),即if(dp[i]+tmp*tmp>=dp[tot]) break; 5、 还有两个for应该这样写 for(int i=0;i<tot;i++) for(int j=i+1;j<=tot;j++) 一开始写成O(n^3)了,感觉自己还是太弱了啊。。。。。。。 还有就是第一个for要从0开始,自己写的时候从1开始,导致WA了,各种原因自己慢慢体会 6、还有用到vector容器来清除标记vis,也起到优化时间的作用

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stack> 5 #include<vector> 6 #include<set> 7 #include<algorithm> 8 using namespace std; 9 #define inf 1<<26 10 #define N 60000 11 int n; 12 int a[N]; 13 int dp[N]; 14 int vis[N]; 15 set<int> s; 16 struct Node 17 { 18 int idd; 19 int num; 20 int rankk; 21 }p[N]; 22 bool cmp1(Node a,Node b) 23 { 24 return a.num<b.num; 25 } 26 bool cmp2(Node a,Node b) 27 { 28 return a.idd<b.idd; 29 } 30 int main() 31 { 32 while(scanf("%d",&n)==1) 33 { 34 for(int i=1;i<=n;i++) 35 scanf("%d",&a[i]); 36 37 //int m=n; 38 int tot=1; 39 p[tot].idd=tot; 40 p[tot++].num=a[1]; 41 for(int i=2;i<=n;i++) 42 { 43 if(a[i]==a[i-1]) 44 continue; 45 else 46 { 47 p[tot].idd=tot; 48 p[tot++].num=a[i]; 49 } 50 } 51 //for(int i=1;i<tot;i++) 52 // printf("---%d %d ",p[i].idd,p[i].num); 53 54 tot--; 55 56 sort(p+1,p+1+tot,cmp1); 57 58 p[1].rankk=1; 59 int w=2; 60 for(int i=2;i<=tot;i++) 61 { 62 if(p[i].num!=p[i-1].num) 63 { 64 p[i].rankk=w; 65 w++; 66 } 67 else 68 { 69 p[i].rankk=p[i-1].rankk; 70 } 71 } 72 73 sort(p+1,p+1+tot,cmp2); 74 for(int i=1;i<=tot;i++) 75 dp[i]=inf; 76 77 vector<int>v; 78 dp[0]=0; 79 dp[tot]=tot; 80 for(int i=0;i<tot;i++) 81 { 82 int tmp=0; 83 for(int j=i+1;j<=tot;j++) 84 { 85 if(!vis[p[j].rankk]) 86 { 87 v.push_back(p[j].rankk); 88 vis[p[j].rankk]=1; 89 tmp++; 90 } 91 if(dp[i]+tmp*tmp>=dp[tot]) break; 92 dp[j]=min(dp[j],dp[i]+tmp*tmp); 93 } 94 for(int i=0;i<v.size();i++) 95 vis[v[i]]=0; 96 v.clear(); 97 } 98 printf("%d ",dp[tot]); 99 } 100 return 0; 101 }