1、自然数的拆分问题

题目描述

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。现在给你一个自然数n,要求你求出n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数n。

输出格式

输出:若干数的加法式子。

输入输出样例

输入 #1

7

输出 #1

1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4
说明/提示

用回溯做,dfs的基本思路,dfs和bfs都是有套路的,多原理晓得了就是自己要多练几遍就知道了

代码
import java.util.Scanner;

public class Main {
    static int n;
    static int[] arr ;
    public static void dfs(int index,int sum){
        if(sum <0){							//剪枝,将不合格的去掉
            return;
        }
        if(sum == 0 ){						//边界条件
            for(int i =1;i<=index -2;i++){
                System.out.print(arr[i]+"+");
            }
            System.out.println(arr[index-1]);
//            System.out.println(arr[index]);
         return;
        }
        for(int i =1;i<n;i++){
            if(i<arr[index-1]) continue;		//这个是为了防止更小的数字再次进入
            arr[index] =i;						//回溯的基本套路
            sum = sum -i;
//            index ++;
            dfs(index+1 ,sum);
//            index--;
//            arr[index] = 0;
            sum = sum+i;
        }
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
         n = cin.nextInt();
         arr = new int[100];
        dfs(1,n);
        cin.close();
    }
}

2、租用游艇

题目描述

长江游艇俱乐部在长江上设置了 n 个游艇出租站 1,2,⋯,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站 i 到游艇出租站 j 之间的租金为 r(i,j)(1≤i<jn*)。试设计一个算法,计算出从游艇出租站 1 到游艇出租站 n 所需的最少租金。

输入格式

第一行中有一个正整数 n,表示有 n 个游艇出租站。接下来的 n-1n−1 行是一个半矩阵 r(i,j)r(i,j)(1≤i<jn)。

输出格式

输出计算出的从游艇出租站 11 到游艇出租站 nn 所需的最少租金。

输入输出样例

输入 #1

3
5 15
7

输出 #1

12

说明/提示

n≤200,保证计算过程中任何时刻数值都不超过 10^6。

代码


import java.util.Scanner;
//写在前面的哈

public class Main {
    static  int n;
    static  int[][] arr;
    static  int res;

    public static void dfs(int index,int sum){
        if(sum > res) return;   //我是在寻找最小值,你没我小就可以走了
        if(index == n){
//            System.out.println("====");
            if(res > sum){
                res = sum;      //求最小代价
            }
            return;

        }
        for(int i =index+1;i<=n;i++){
            //其中dfs表示第一个参数 表示下一个即将要到达的租户站
            //第二个参数表示权值
            dfs(i,sum +arr[index][i]);
        }
    }
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        n = cin.nextInt();
        arr = new int[n+1][n+1];
        //转存图,长知识了,图原来也可以这样玩大佬别喷,蒟蒻瑟瑟发抖
        for(int i =1;i<n ;i++){
            for(int j =i +1;j<=n;j++){
                arr[i][j] =cin.nextInt();
            }
        }
        res = 999999;
        dfs(1,0);
        System.out.println(res);
        cin.close();
    }
}

posted on 2020-03-25 10:49  jwthong  阅读(130)  评论(0)    收藏  举报