hdoj_2079_选课时间(java实现)

原题链接

http://acm.hdu.edu.cn/showproblem.php?pid=2079

 

思路:一开始看到有些懵,很像之前做的一道换零钱的题目,但是这里由于具体科目数不知道,所以只能用递归做,然后没头绪上网搜了一下,看到了有人用dfs,就试着写了一下,有了如下代码

package hduoj;

import java.util.Scanner;

public class hdoj_2079 {
    private static int kind = 0;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = sc.nextInt();
        while(count-- != 0){
            int score_sum = sc.nextInt();
            int k = sc.nextInt();
            int[][] data = new int[k][2];
            for(int i = 0;i<k;++i){
                data[i][0] = sc.nextInt();
                data[i][1] = sc.nextInt();
            }
            kind = 0;
            int[] temp = new int[k]; 
            dfs(score_sum,k,data,temp,0,0);
            System.out.println(kind);
        }
    }

    private static void dfs(int score_sum,int k,int[][] data,int[] temp,int sum,int index){
        if(sum == score_sum){
            kind++;
            return;
        }
        if(sum>score_sum||temp[index]>data[index][1]){
            return;
        }
        for(int i = 0;i<k;++i){
            temp[i]++;
            dfs(score_sum,k,data,temp,sum+data[index][0],i);
            temp[i]--;//回溯
        }
    }

}

然后当然是错的第二组测试数据大了很多,估计是有很多重复数据,因为“同等分数的课没有区别”,而且先选和后选没有区别(就是最终的科目种类一样就算相同的选法,顺序无所谓),然后就去搜了下别人的代码,看到dalao是用外界传入参数来判断遍历所有的科目,然后内部循环控制选课的数量,这样就避免了重复(因为每次选课的数量都唯一,这样就不存在重复),代码如下:

package hduoj;

import java.util.Scanner;

public class hdoj_2079 {
    //使用dfs来遍历(普通遍历不行,会有超级多的重复项——需要保证唯一性)
    private static int kind = 0;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = sc.nextInt();
        while(count-- != 0){
            int score_sum = sc.nextInt();
            int k = sc.nextInt();
            int[][] data = new int[k][2];
            for(int i = 0;i<k;++i){
                data[i][0] = sc.nextInt();
                data[i][1] = sc.nextInt();
            }
            kind = 0;
            dfs(score_sum,k,data,0,0);
            System.out.println(kind);
        }
    }

    private static void dfs(int score_sum,int k,int[][] data,int sum,int index){
        if(sum == score_sum){
            kind++;
            return;
        }
        if(sum>score_sum||index==k){
            return;
        }
        for(int i = 0;i<=data[index][1];++i){
            dfs(score_sum,k,data,sum+i*data[index][0],index+1);
        }
    }

}

 

代码已经ac

希望对大家有所帮助

以上

 

posted @ 2020-03-05 15:51  醉生梦死_0423  阅读(253)  评论(0编辑  收藏  举报