zoukankan      html  css  js  c++  java
  • ccf 201612-4 压缩编码(DP)(100)

    ccf 201612-4 压缩编码

    问题分析:

    解决本问题,首先需要知道哈夫曼编码。参见:哈夫曼编码_百度百科

    这是一个编码问题,似乎可以用哈夫曼编码来解决,但是略有不同的地方在于“每个字符的编码按照字典序排列后的顺序与原先顺序一样”。

    所以无法每次取出权值最小的两个节点,而只能选择相邻的节点,到底选择哪两个相邻节点,这便是石子问题

    设dp[i][j]表示第i到第j堆石子合并的最优值,sum[i][j]表示第i到第j堆石子的总数量。那么就有状态转移公式:

    1、dp[i][j]=0 (i==j)

    2、dp[i][j]=min(dp[i][k]+dp[k][j])+sum[i][j] (i!=j)

    此时算法复杂为O(n^3)。

    这里可以利用平行四边形优化降为O(n^2):

    由上面的方程式可知我们每次求dp[i][j]的关键是找到合适的k值,设p[i][j]为dp[i][j]的这个合适的k值,根据平行四边形规则有以下不等式:p[i][j-1]<=p[i][j]<=p[i+1][j]。

    那么求解dp[i][i+L](L为长度)的复杂度就为:

    (p[2,L+1]-p[1,L])+(p[3,L+2]-p[2,L+1])…+(p[n-L+1,n]-p[n-L,n-1])=p[n-L+1,n]-p[1,L]≤n。

    复杂度为O(n)。然后L从1循环至n,总复杂度就为O(n^2)。

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int maxn = 1000+5;
     5 const int INF = 0x7f7f7f7f;
     6 int dp[maxn][maxn];
     7 int sum[maxn],num[maxn];//sum为1~i的总权重 
     8 int n;
     9 
    10 int main()
    11 {
    12     cin>>n;
    13     for(int i=1;i<=n;i++)
    14     {
    15         cin>>num[i];
    16     }
    17     sum[0] = 0;
    18     memset(dp,INF,sizeof(dp));
    19     for(int i=1;i<=n;i++)
    20     {
    21         sum[i] = sum[i-1] + num[i];
    22         dp[i][i] = 0;
    23      } 
    24      for(int i=2;i<=n;i++)
    25      {
    26          for(int j=1;j<=n-i+1;j++)
    27          {///填写dp[j][m] 
    28              int m = j+i-1;//纵坐标 
    29              //k为划分点 
    30              for(int k=j;k<m;k++)
    31              {
    32                  if(dp[j][k] + dp[k+1][m] + sum[m]-sum[j-1] < dp[j][m])
    33                  dp[j][m] = dp[j][k] + dp[k+1][m] + sum[m]-sum[j-1];
    34              }
    35           }
    36      }
    37     cout<<dp[1][n]<<endl;
    38     return 0;
    39  } 
  • 相关阅读:
    准确率99.9%的离线IP地址定位库
    手写一个消息队列以及延迟消息队列
    rabbitmq介绍
    污点和亲和力高级调度方式
    ceph
    Vue作业
    label和labelSeletor
    http状态简记
    数据库
    作业
  • 原文地址:https://www.cnblogs.com/yxh-amysear/p/8578022.html
Copyright © 2011-2022 走看看