题目描述
给出一个数列 ,把 分为 段,
对于每一段编码位数
表示该段有多少个数, 表示该段中最大的数用二进制表示有多少位
题目解析
,设 表示编到第 位的最小编码位数
因为每个 作为一段的首位,所以可以从后往前推
对于每个 可以分为一段,则该段最长长度为 ,所以判断一下,不越界即可
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int n,x;
int a[30005],f[30005];
int main()
{
freopen("coding.in","r",stdin);
freopen("coding.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
while(x)
{
a[i]++;
x>>=1;
}
}
for(int i=1;i<=n;i++)
f[i]=1e9;
for(int i=n;i>=1;i--)
{
f[i]=f[i+1]+12+a[i];
int maxn=a[i];
for(int j=i+2;j<=min(i+255,n+1);j++)
{
maxn=max(maxn,a[j-1]);
f[i]=min(f[i],f[j]+(j-i)*maxn+12);
}
}
printf("%d",f[1]);
return 0;
}