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
     
  • 相关阅读:
    Nginx 提示host not found in upstream 错误解决方法
    使用Vmware CLI 6.5控制虚拟机,并做快照
    在 Windows服务器中启用/禁用SMBv1、SMBv2和SMBv3的方法
    使用python调用wps v9转换office文件到pdf
    Tomcat延迟启动
    配置frp
    PowerDesigner逆向生成MYSQL数据库表结构总结
    windows下载安装MariaDB10.2.17 绿色版
    Mosquitto --topic
    Jmeter也能IP欺骗!
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/4738126.html
Copyright © 2011-2022 走看看