• [HDU] 1789 Doing Homework again


    题目链接:

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

    方法:

    既然一个作业超期了,不管超期多久都只扣一次固定的学分。又因为每个作业只要一天,所以可以看出n个作业n天就可以做完,那些截至日期大于n天的就不用考虑了。只考虑截至日期在n天内的。可以这样考虑,设截至日期在n天内的作业如果全部按时完成的话得到的学分的和是sum,再设一个实际获得学分t_sum(初始0),然后一个作业按时完成 t_sum就加上学分,超期的就不管,然后把原来的问题转变为在截至日期在n天内的作业中安排一个顺序使得获得的学分之和t_sum最大,然后用sum-t_sum得到扣除的最少学分,这样得到原来问题的解。

    设D[i]为一个截至日期,D[i].values截至日期是D[i]的作业有哪些,然后从第一天开始计算,计算第D[i]前必须做完的作业中选择D[i]个作业来做能获得的最大学分,计算过程为,首先计算截止期是第一天的作业,从D[1].values选择出最高学分那个,当然只选1个,然后把它并入D[2].values,再选出2个最高学分的作业,然后再将这两个并入D[3].values,再选出3个最高分的哪个。。。。最后在D[n].values中选择最高分的n个作业,将学分相加得到t_sum。

    问题解决了。

    代码:

    #include <iostream>
    #include <queue>
    using namespace std;
    int n;
    struct Course
    {
        int deadLine;
    	int get;
    };
    struct DeadLine
    {
    	priority_queue<int> values;
    };
    Course courses[1001];
    DeadLine deadlines[1001];
    int main()
    {
        int tc=0;
        scanf("%d",&tc);
        while(tc>0)
        {
            scanf("%d",&n);
            int sum = 0;
            for(int i =1;i<=n;i++)
                scanf("%d",&courses[i].deadLine);
            for(int i =1;i<=n;i++)
                scanf("%d",&courses[i].get);
    		priority_queue<int> no_values ;
    		for(int i =1;i<=1000;i++)
    			deadlines[courses[i].deadLine].values = no_values;
    		for(int i =1;i<=n;i++)
    		{
    			if(courses[i].deadLine<=n)
    			{
    				sum+=courses[i].get;
    				deadlines[courses[i].deadLine].values.push(courses[i].get);
    			}
    		}
    		int re =0;
    		for(int i=1;i<=n;i++)
    		{
    			int t_re = 0;
    			priority_queue<int> t_values = deadlines[i].values;
    			if(!deadlines[i].values.empty())
    			{
    				int j=0;
    				while(j<i && !deadlines[i].values.empty())
    				{
    					t_re+=deadlines[i].values.top();
    					deadlines[i].values.pop();
    					j++;
    				}
    			}
    			re = re>t_re ?re :t_re;
    			bool foundOne =false;
    			int k=i;
    			while(k<n)
    			{
    				if(!deadlines[k+1].values.empty())
    				{
    					foundOne =true;
    					break;
    				}
    				k++;
    			}
    			if(foundOne)
    			{
    		  
    				int j=0;
    				deadlines[i].values = t_values;
    				while(j<i && !deadlines[i].values.empty())
    				{
    					deadlines[k+1].values.push(deadlines[i].values.top());
    					deadlines[i].values.pop();
    					j++;
    				}
    				i=k;
    				
    			}
    		}
    		cout<<sum-re<<endl;
            tc--;
        }
        return 0;
    }
    

     感想:模拟,注意代码中基于概率优化的部分

  • 相关阅读:
    第四次作业--个人作业--软件案例分析
    第五次作业--团队项目--需求规格说明书
    Beta版本的贡献率
    软工实践总结
    beta版本冲刺第四天
    beta版本冲刺第三天
    beta版本冲刺第一天
    Beta版本冲刺计划及安排
    团队项目冲刺总结
    项目冲刺第六天
  • 原文地址:https://www.cnblogs.com/kbyd/p/3238608.html
Copyright © 2020-2023  润新知