首页新闻找找看学习计划

一道知乎的编程题

0
悬赏园豆:20 [待解决问题]
题目描述:小王计算机学院三年级本科生。他平时比较贪玩,这个学期就要结束了,每个课程大作业的截止时间也快到了,可是小王还没有开始做。每一门课程都有一个课程大作业,每个课程大作业都有截止时间。如果提交时间超过截止时间X天,那么他将会被扣掉X分。对于每个大作业,小王要花费一天或者若干天来完成。他不能同时做多个大作业,只有他完成了当前的项目,才可以开始一个新的项目。小王希望你可以帮助他规划出一个最好的办法(完成大作业的顺序)来减少扣分。

输入描述:输入包含若干测试样例。 输入的第一行是一个正整数T,代表测试样例数目。 对于每组测试样例,第一行为正整数N(1 <= N <= 15)代表课程数目。 接下来N行,每行包含一个字符串S(不多于50个字符)代表课程名称和两个整数D(代表大作业截止时间)和C(完成该大作业需要的时间)。 注意所有的课程在输入中出现的顺序按照字典序排列。

输出描述:对于每组测试样例,请输出最小的扣分以及相应的课程完成的顺序。 如果最优方案有多个,请输出字典序靠前的方案。
示例1
输入2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
输出2
Computer
Math
English
3
Computer
English
Math

(Hint:
第二个测试样例, 课程完成顺序Computer->English->Math 和 Computer->Math->English 都会造成3分罚分, 但是我们选择前者,因为在字典序中靠前)
luoyin500的主页 luoyin500 | 初学一级 | 园豆:89
提问于:2018-04-10 15:13

大哥,你这提问的太频繁了。上个知乎的题目还没理论AC,又来了一个。你有没有想过豆子用完了怎么办?

Shendu.cc 2年前

@Shendu.cc: 看到标题“一道XXX的编程题”我就猜到是他了...

写代码的相声演员 2年前
< >
分享
所有回答(1)
0

···java
package cnblogs.bestcourseseq;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class BestCourseSeq
{
public String bestSeq(int[][] cs)
{
int n = cs.length;
StringBuilder[] allSeq = allSeq(n);
int max = Integer.MIN_VALUE;
List<String> results = new ArrayList<>();

    for(StringBuilder sb: allSeq)
    {
        boolean[] complete = new boolean[n];
        int[][] courses = new int[cs.length][cs[0].length];
        for(int x = 0; x < cs.length; x++)
        {
            for(int y = 0; y < cs[0].length; y++)
            {
                courses[x][y] = cs[x][y];
            }
        }
        for(int i = 0; i < sb.length(); i++)
        {
            int temp = Integer.parseInt(String.valueOf(sb.charAt(i)));
            for(int j = 0; j < courses.length; j++)
            {
                if(!complete[j])
                {
                    courses[j][0] -= courses[temp-1][1];
                }
            }
            
            complete[temp - 1] = true;
        }
        
        int tempDays = 0;
        for(int i = 0; i < courses.length; i++)
        {
            if(courses[i][0] < 0)
            {
                tempDays += courses[i][0];
            }
        }
        
        if(tempDays >= max)
        {
            if(tempDays > max)
            {
                max = tempDays;
                results.clear();
                results.add(sb.toString());
            }
            else
            {
                results.add(sb.toString());
            }
        }
    }
    
    int min = Integer.MAX_VALUE;
    for(int i = 0; i < results.size(); i++)
    {
        if(Integer.parseInt(results.get(i)) < min)
        {
            min = Integer.parseInt(results.get(i));
        }
    }
    
    return String.valueOf(min);
}

public StringBuilder[] allSeq(int n)
{
    if(n == 1)
    {
        return new StringBuilder[]{new StringBuilder(n+"")};
    }
    
    StringBuilder[] nseq = new StringBuilder[factorial(n)];
    StringBuilder[] nminus1seq = allSeq(n-1);
    int k = 0;
    
    for(int i = 0; i < nminus1seq.length; i++)
    {
        for(int j = 0; j < n; j++)
        {
            StringBuilder temp = new StringBuilder(nminus1seq[i].toString());
            temp.insert(j, n+"");
            nseq[k++] = temp;
        }
    }
    
    return nseq;
}

public int factorial(int n)
{
    if(n == 1)
    {
        return 1;
    }
    
    return factorial(n - 1) * n;
}

@Test
public void test()
{
    String[] courses = {"course1","course2","course3"};
    int[][] arr = {{3,3},{6,3},{6,3}};
    String seq = bestSeq(arr);
    for(int i = 0; i < seq.length(); i++)
    {
        int temp = Integer.parseInt(String.valueOf(seq.charAt(i)));
        System.out.println(courses[temp-1]);
    }
}

}
```
少于十门课可以向上面这样做,首先找出所有可能的写作业的顺序,然后计算每种顺序下会超的天数(即会扣的分),找出扣分最少的,然后从扣分最少的中找出字典序靠前的,这面只能处理十种以下是因为只考虑了一位数字的情况

流年飞雨 | 园豆:1978 (小虾三级) | 2018-04-11 20:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册