IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 附加条件的0-1背包问题 -> 正文阅读

[数据结构与算法]附加条件的0-1背包问题

前言

水一篇博文证明我还活着~

问题描述(0-1背包问题)

ok,咱们先来说说这个背包问题是怎么样的呢。
首先背包问题就是,在一个有限的背包内,尽可能去装下更多的物品,每个物品都是有自己的质量和价值的,我们要让价值最大化!

那么在这里我们先来说说,为什么背包问题可以是一个动态规划的题目,对于动态规划有一个明显的特征,当前状态取决于上一个状态,例如斐波那契数列(当然关于斐波那契数列我们又可以使用矩阵幂乘法来加速解决问题)。那么在背包问题里面,显然,下一个物品要不要放置,取决于当前的背包容量和上一个物品有没有放置,之后放置之后的值就是 max(没有放置上一个物品,放置了上一个物品)而,上一个物品又是取决于上上个物品和上物品,这样我们发现这个就相当于变成了走楼梯,斐波那契数列的问题。这样一来我们就懂了,背包问题其实就是在原来简单的动态规划的前提下,加入了最大化(最小化)的约束,也就是多加了一个约束!

那么在理解了背包问题之后,我们来说说在蓝桥杯题目里面我见到的类似背包问题的题目,首先最明显的就是那个走格子问题,在格子上面有一定的value,然后让这个value最大。

例如:

image.png

那这个呢,怎么说呢,就是在有限的空间内,或者是一个限制之内,放置最多的物品去达到最大的价值。

打表

想要搞清楚这个问题呢,咱们还是得打表。

在这里插入图片描述

此外咱们还有两个数组分别表示重量和价值。

这里的话我不太想了复述了,前面的话是有写过的。
我今天这里只说一下那个附加条件的怎么做。

题目

在这里插入图片描述

思路

首先很明显是个背包问题,但是这里有些个条件要处理一下。

原来我们考虑背包的话只是需要考虑那个背包的容量,那么这里的就是不仅要考虑这个,还要考虑那个不能相交的条件。

然后在这里引出了一个问题,就是我们在dp的时候是在做选择,那么我如何知道我选择了哪些商品的问题。所以需要你对这个0-1背包问题比较熟练。然后知道如何处理之后,咱们就能够动手了。

代码

package com.huterox.testweek02;

import java.util.ArrayList;
import java.util.Scanner;

public class week209 {
    //目前的想法就是暴力搜索

//6
//1 1 2
//1 4 2
//1 7 2
//4 1 2
//4 4 2
//4 7 2


    static ArrayList<ArrayList<Integer>> trees = new ArrayList<>();

    public static void main(String[] args) {
        //初始化,我们把这个当作有约束的0-1背包问题
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] w = new int[n];
        int totalArea  = 0;
        for (int i=0;i<n;i++){
            ArrayList<Integer> temp = new ArrayList<>();
            int row  = scanner.nextInt();
            int col = scanner.nextInt();
            int r = scanner.nextInt();
            totalArea+=r*r;//边界限制
            temp.add(row);
            temp.add(col);
            temp.add(r);
            w[i] = r*r;
            trees.add(temp);
        }

        int[] dp = new int[totalArea+1];
        int[] place = new int[n];
        dp[0]=0;
        for (int i=0;i<trees.size();i++){
            for (int j=totalArea;j>=w[i];j--) {
                if (i == 0) {
                    //此时是种第一颗树
                    dp[j] = Math.max(dp[j], dp[j - w[i]] + w[i]);
                    place[i] = i;
                }
                else  {
                    //把其他的树种下去
                    if(j - w[i]>=0)
                    {
                        int lay_now  =  dp[j - w[i]] + w[i];
                        if(lay_now>=dp[j]){
                            //这里需要轮询判断
                            boolean flag = true;
                            for (int k=0;k<=i-1;k++){
                               if(!is_vaild(trees.get(i),trees.get(place[k]))){
                                   flag = false;
                               }
                            }

                            if(flag){
                                place[i] = i;
                                dp[j] = lay_now;
                            }else
                                place[i] = place[i-1];
                        }
                        else {
                            dp[j] = dp[j];
                            place[i] = place[i-1];
                        }
                    }

                }
            }
        }

        System.out.println(dp[totalArea]);
        System.out.println("种了这几颗树");
        for (int s : place) {
            System.out.printf("%d--",s);
        }

    }

    public static boolean is_vaild(ArrayList<Integer> last,ArrayList<Integer> now){
        //判断当前的树和即将种下的树有没有冲突,条件判断出问题了
        double cha_x = (double)last.get(0) - now.get(0);
        double cha_y = (double)last.get(1)-now.get(1);
        double distance = (double)last.get(2)+last.get(2);
        return (Math.pow(cha_x, 2) + Math.pow(cha_y, 2) >= Math.pow(distance, 2));
    }
}

可以看到种了1 3 5这三棵树
在这里插入图片描述
ok, 水玩了~

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:17:10  更:2022-03-21 21:21:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:38:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码