蓝桥 最小乘积(基本型) dfs

问题描述
  给两组数,各n个。
  请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小。要求程序输出这个最小值。
  例如两组数分别为:1 3  -5和-2 4 1

  那么对应乘积取和的最小值应为:
  (-5) * 4 + 3 * (-2) + 1 * 1 = -25
输入格式
  第一个行一个数T表示数据组数。后面每组数据,先读入一个n,接下来两行每行n个数,每个数的绝对值小于等于1000。
  n<=8,T<=1000
输出格式
  一个数表示答案。
样例输入
2
3
1 3 -5
-2 4 1
5
1 2 3 4 5
1 0 1 0 1

样例输出

-25

6

思路:

 

对于a,b两个数组 dfs第一个数组的每个值 然后对于每一次dfs 依次循环b数组的值 使用一个值就标记表示这个值已使用 然后统计sum的最小值

还有一种做法是把两个数组排序 一个升序 一个降序 然后遍历两个数组 依次最大值*最小值就是res 但是我没想到 还是直接用暴力

 1 import java.util.Scanner;
 2 public class 最小乘积 {
 3     static final int N=10;
 4     static int m;
 5     static int n;
 6     static int q[]=new int[N]; //q和a数组为输入的两个数组
 7     static int a[]=new int[N]; 
 8     static long sum;
 9     static long res=Integer.MAX_VALUE;
10     static boolean vis[]=new boolean[N];
11        public static void main(String[] args) {
12         Scanner sc=new Scanner(System.in);
13         m=sc.nextInt();
14         while(m-->0){
15             n=sc.nextInt();
16           for(int i=1;i<=n;i++){            
17               q[i]=sc.nextInt();
18           }
19           for(int i=1;i<=n;i++){            
20               a[i]=sc.nextInt();
21           }
22           dfs(1);
23           System.out.println(res);
24           res=Integer.MAX_VALUE;//每一组数组完成 res都要重新赋为最大值 防止对下一组数据产生影响
25         }
26     }
27        static void dfs(int u){
28            if(u>n){           
29                res=Math.min(res, sum);
30                return;
31            }
32            for(int i=1;i<=n;i++){
33                if(!vis[i]){  //如果在b数组中这个值没有访问过 就执行
34                    vis[i]=true;
35                    sum += q[u]*a[i]; //使用这个值
36                    dfs(u+1);
37                    vis[i]=false;
38                    sum -= q[u]*a[i];
39                }
40            }
41        }
42 }

 

posted @ 2021-03-13 22:31  nb小歪  阅读(99)  评论(0)    收藏  举报