zoukankan      html  css  js  c++  java
  • hdu 5009 Paint Pearls (dp)

    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.
     
    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.
     
    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 }
    View Code
     
  • 相关阅读:
    C++并发与多线程学习笔记--unique_lock详解
    C++并发与多线程学习笔记--互斥量、用法、死锁概念
    MongoDB教程--配置与入门
    C++并发与多线程学习笔记--多线程数据共享问题
    C++并发与多线程学习笔记--参数传递详解
    C++并发与多线程学习笔记--基本概念和实现
    Python学习笔记--语音处理初步
    C#中三个关键字params,Ref,out
    Windows窗体应用开发3--配置标准控件1
    在博客的第一天
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/4738126.html
Copyright © 2011-2022 走看看