0-1 knapsack problem with additional conditions

foreword

A blog post on water proves that I am still alive~

Problem description (0-1 knapsack problem)

ok, let's talk about the backpack problem first.
First of all, the backpack problem is, in a limited backpack, as many items as possible, each item has its own quality and value, we must maximize the value!

So let's first talk about why the knapsack problem can be a dynamic programming problem. There is an obvious feature for dynamic programming. The current state depends on the previous state, such as the Fibonacci sequence (of course, about Fibonacci Sequences we can use matrix power multiplication to speed up the problem). Then in the backpack problem, obviously, whether to place the next item depends on the current backpack capacity and whether the previous item is placed, and the value after placement is max (the previous item is not placed, the previous item is placed) and , the previous item depends on the previous item and the previous item, so we find that this is equivalent to taking the stairs, the problem of the Fibonacci sequence. In this way, we understand that the knapsack problem is actually adding a maximization (minimization) constraint under the premise of the original simple dynamic programming, that is, an additional constraint!

Then after understanding the knapsack problem, let's talk about the problems similar to the knapsack problem that I saw in the blue bridge cup problem. The first and most obvious one is the problem of walking the grid. There is a certain value on the grid, and then let this value maximum.

E.g:

image.png

What about this, how do you say it, is to place the most items in a limited space, or within a limit, to achieve the greatest value.

By meter

To figure this out, we still have to make a table.

insert image description here

Additionally we have two arrays representing weight and value respectively.

I don't really want to repeat the words here. The previous words have been written.
Today I will only talk about how to do the additional condition.

topic

insert image description here

ideas

It's obviously a knapsack problem at first, but there are a few conditions to deal with here.

It turns out that when we consider a backpack, we only need to consider the capacity of that backpack, so here is not only to consider this, but also to consider the condition that cannot intersect.

Then there is a question here, that is, we are making choices when we are dp, so how do I know which products I have selected. So you need to be more proficient in this 0-1 knapsack problem. Then after we know how to deal with it, we can do it.

code

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));
    }
}

It can be seen that the three trees 1 3 5 are
insert image description here
ok, and the water is playing~

Guess you like

Origin blog.csdn.net/FUTEROX/article/details/123619416