动态规划——图像压缩问题

动态规划——图像压缩问题

问题:

图象压缩问题要求确定象素序列{p1 ,p2 ,…,pn}的最优分段,使得依此分段所需的存储空间最少。每个分段的长度不超过256位。

问题描述比较复杂,复习时间比较紧张,此处不贴了。

分析:

s[i]:子结构。p1,p2,…pi在最优分段时所需的位数

s[i]应该为所有划分方式中位数最少的那一种,为此需要遍历所有的划分方式。

据此递推公式如下:

s[i] = min_1<=k<=min{i,256}_{s[i-k] + k*bmax(i-k+1,i)} + 11

s[i-k]:划分一段后剩下的像素

k:该分段划出的像素的数量

bmax(i,j):表示第i个到第j个下标的像素中最大的那个像素(最大256)所需的位数

11:表示该分段中一共有多少个像素(最大256)以及表示每个像素需要几位(最大8位),共11位

代码:

#include <bits/stdc++.h>

using namespace std;

// 记录序列p中第i到第j个像素中最大的那个用二进制需要多少位
int bmax(int i,int j,int p[]){
    int maxp = -1;
    for(int k = i;k <= j;k++){
        if(p[k] > maxp){
            maxp = p[k];
        }
    }
    int bits = 1;
    maxp = maxp/2;
    while(maxp){
        bits++;
        maxp = maxp/2;
    }
    return bits;
}

// 图像压缩算法,给出分段
// 输入:像素数量n,像素序列p,前i个像素最优分段,分段位置记录矩阵b
void compress(int n, int p[], int s[], int b[]){
    int Lmax = 256,header = 11;
    // 初始化
    s[0] = 0;
    // 计算
    for(int i = 1;i <= n;i++){
        int mins = 0x3f3f3f;
        for(int k = 1;k <= min(i,Lmax);k++){
            int temp = s[i-k] + k*bmax(i-k+1,i,p);
            if(temp < mins){
                mins = temp;
                b[i] = i-k;
            }
        }
        s[i] = mins + header;
    }
}

// 根据记录矩阵b还原最优解
void traceback(int b[],int i,int p[]){
    if(i==0) return ;
    traceback(b, b[i], p);
    for(int j = b[i]+1;j <= i;j++)
        cout<<p[j]<<" ";
    cout<<endl;
}

int main(){
    int p[7] = {0, 10, 12, 15, 255, 1, 2};
    int s[7],b[7];
    memset(s, 0, sizeof(s));
    memset(b, 0, sizeof(b));
    compress(6, p, s, b);
    cout<<s[6]<<endl;
    traceback(b, 6, p);
}

复杂度:

时间复杂度:O(n)

空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值