图片压缩及最小m段子序列和算法

文章介绍了使用动态规划方法解决图像压缩问题,通过迭代找到最优像素段累计实现压缩。同时,展示了如何应用动态规划求解随机序列的最小分组最大字段合,以达到优化结构的目的。

方法均为动态规划。

图片压缩算法

动态规划DP,以最优分段累计与当前最优分段迭代得解。(注意这里的log是底数为2 的)

代码:

    /**
     * 压缩图像算法
     * @param n 像素点数
     * @param p 对应的n个像素点值
       s m个像素段(1 <= m <= n)对应最优压缩结果
     * @param l 像素段下包含的像素点数
     * @param b 像素段下记录最长的像素点二进制位数,并对数化(底数为2)处理以得二进制高位
     * @return 返回s[n]压缩结果,DP最终累计值
     */
    private static int compress(int n, int p[], int l[], int b[]) {
        // 0索引位无意义,仅用于迭代,DP中往往对应实际逻辑意义,Java中默认int数组为0
        int s[] = new int[n + 1];
        int bitMax = 256;
        // 头信息长 b + l
        int header = 11;

        // 从低位向高位迭代,
        for (int i = 1; i <= n; i++) {
            // 会被最小的代替(int位上限值)
            s[i] = Integer.MAX_VALUE;
            b[i] = (int) (Math.log(p[i - 1]) / Math.log(2)) + 1;
            int bmax = b[i];

            // 一个分段最少一个像素
            l[i] = 1;

            for (int j = 1; j <= bitMax && j <= i; j++) {
                bmax = Math.max(bmax, b[i - j]);
                int curS = s[i - j] + j * bmax;
                if (s[i] > curS) {
                    s[i] = curS;
                    l[i] = j;
                }
            }

            // 每个优化分段必须带一个头信息长
            s[i] += header;
        }
        System.out.print("数组s:");
        printArr(s);
        return s[n];
    }

最小m段子序列和

类似问题一的思路,不过多了一层按m个分段值去构造优化结构。

    /**
     * 按随机序列的最小分组最大字段合
     * @param arr 随机数组
     * @param m m段
     */
    private static void caculSpeSum(int[] arr, int m) {
        int n = arr.length;
        int[][] dp = new int[n + 1][m + 1];

        for (int i = 1; i <= n; i++) {
            // 初始化
            dp[i][1] = dp[i - 1][1] + arr[i - 1];

            for (int j = 2; j <= m; j++) {
                int minValue = Integer.MAX_VALUE;
                for (int k = 1; k <= i; k++) {
                    // arr[1-k]最优与arr[k+1]~arr[i]分段
                    int curValue = Math.max(dp[k][j - 1], dp[i][1] - dp[k][1]);
                    minValue = Math.min(minValue, curValue);
                }
                dp[i][j] = minValue;
            }
        }

        System.out.println("结果:" + dp[n][m]);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值