概述
问题描述
图像的变位压缩存储格式将所给的像素点序列{p1,p2,…,pn},0≤pi≤255分割成m个连续段S1,S2,…,Sm。第i个像素段Si中(1≤i≤m),有l[i]个像素,且该段中每个像素都只用b[i]位表示。
由于,b[i]<=8,需要用3位表示b[i];如果限制1<=l[i]<=256,则需要用8位表示l[i]。因此,第i个像素段所需的存储空间为l[i]*b[i]+11位。11是header,用来标记每段的特征的。
按此格式存储像素序列{p1,p2,…,pn},需要
∑
i
=
1
m
i
=
l
[
i
]
∗
b
[
i
]
+
11
m
sum_{i=1}^mi=l[i]*b[i]+11m
∑i=1mi=l[i]∗b[i]+11m 位。
压缩则是就是把序列{p1,p1,……pn}进行设断点,将其分割成一段一段的。分段的过程就是要找出断点,让一段里面的像素的最大灰度值比较小,那么这一段像素(本来需要8位)就可以用较少的位(比如7位)来表示,从而减少存储空间。
这里我们对上图分组:
第一组4个数,最大是7所以用3位表示;
第二组2个数,最大是245所以用8位表示;
第三组6个数,最大是28所以用5位表示;
这个时候,我们最后得到了最后的位数结果为:4*3+2*8+6*5+11*3=91。
思路
第一想法:暴力枚举。细想发现实现比较困难,因为每段长度不定。
这次的目的是寻找最小值,仔细想来还得是动态规划,从最优子结构推至全局最优解。那么还是原来的问题,最优子结构应该长什么样?
假设第i个数长度是k,maxlen(i,j)用于寻找[i,j]中的最大长度,最优子结构应该为:
d
p
[
i
]
=
m
a
x
(
d
p
[
i
−
1
]
+
k
+
h
e
a
d
e
r
,
d
p
[
i
−
t
]
+
t
∗
m
a
x
l
e
n
(
i
−
t
,
i
)
)
dp[i] = max(dp[i-1]+k+header, dp[i-t]+t*maxlen(i-t, i))
dp[i]=max(dp[i−1]+k+header,dp[i−t]+t∗maxlen(i−t,i))
因此只需递归至dp[n]即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define MAX 256
int main(){
int n;
scanf("%d", &n);
int a[n],dp[n+1];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
char result[10];
itoa(a[i],result,2); // 进制转换
a[i] = strlen (result);
}
dp[0]=0;
for(int i=0;i<n;i++){
int maxlen = a[i]; // 假设这个最长
dp[i+1] = dp[i]+a[i]; // 假设是要直接接上去的
for(int len_picture=1; len_picture<=MAX && len_picture<=i+1; len_picture++){
maxlen = max(maxlen, a[i-len_picture+1]);
dp[i+1]=min(dp[i+1], dp[i+1-len_picture]+len_picture*maxlen);
}
dp[i+1]+=11;
// for(int j=0;j<=i+1;j++)
// printf("%dn",dp[j]);
// printf("n");
}
}
//测试数据:
//6 10 12 15 255 1 2
主要的难点是理解题目和考虑循环中的临界值。
最后
以上就是呆萌花生为你收集整理的图像压缩 动态规划C语言实现的全部内容,希望文章能够帮你解决图像压缩 动态规划C语言实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复