zoukankan      html  css  js  c++  java
  • [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;
    }
    

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

  • 相关阅读:
    Hive学习小记-(4)带复杂集合类型及指定多分隔符hive建表
    nowcoder-shell篇(grep、awk、sed为主)
    剑指offer02-替换空格
    剑指offer67-剪绳子**
    爬虫5-Scrapy爬虫架构
    爬虫4-网站结构分析
    爬虫3-python爬取非结构化数据下载到本地
    项目创建
    项目框架搭建
    项目表结构
  • 原文地址:https://www.cnblogs.com/kbyd/p/3238608.html
Copyright © 2011-2022 走看看