贪心练习 hdu1789
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心练习 hdu1789相关的知识,希望对你有一定的参考价值。
贪心算法
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。(摘自百度百科)
贪心选择
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终能得到问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪心选择开始的,而且作了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步贪心选择,最终可得到问题的一个整体最优解。
最优子结构
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法或动态规划算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响,而动态规划则不是。贪心算法对每个子问题的解决方案都做出选择,不能回退;动态规划则会根据以前的选择结果对当前进行选择,有回退功能。动态规划主要运用于二维或三维问题,而贪心一般是一维问题[2] 。
摘自百度百科;
个人理解:处理此类题目主要是寻求最优解,也就是寻求一个好的贪心策略;一般在题目中都会运用结构体来定义变量,这样方便进行处理及定位,然后会使用排序,按照题意选择排序顺序。最后进行数据的逐个处理,选择或是放弃。以达到贪心目的。获得最优解。
还没学动态规划,额。也许说的并不准。。。
例题
A - Doing Homework again HDU - 1789
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
Input
The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
Output
For each test case, you should output the smallest total reduced score, one line per test case.
Sample Input
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4
Sample Output
0
3
5
本题题意是 一个娃娃做作业,没做完的要扣分,每门作业都有最后期限。问如何安排扣分最少。
输入第一行是几组测试样例,样例第一行是有几门作业,第二行是对应分数。输出最小的扣分。
解题思路:按照分数排序,先做分高的 ,如果分数一样,把期限小的排在前面,然后创建一个标记数组,按顺序做作业,今天做的作业的期限往前找标记数组,如果被占用就继续往前找,如果找不到,就把分数加在扣分里代表,没完成。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxnum 1010
using namespace std;
int use[maxnum];
typedef struct node
{
int deadline;
int score;
}ss;
int cmp(ss a , ss b)
{
if(a.score != b.score)
return a.score > b.score;
else
return a.deadline < b.deadline;
}
int main()
{
int n;
scanf("%d",&n);
while (n--)
{
int t;
ss a[maxnum];
scanf("%d",&t);
for (int i = 0 ; i < t ;i++)
scanf("%d",&a[i].deadline);
for (int i = 0 ; i < t; i++)
scanf("%d",&a[i].score);
sort (a,a+t,cmp);
int sum = 0 , j;
memset(use,0,sizeof(use));
for (int i = 0 ; i < t ;i++)
{
for (j = a[i].deadline ; j > 0 ;j--)
{
if(!use[j])
{
use[j] = 1;
break;
}
}
if(j == 0)
sum += a[i].score;
}
printf("%d\n",sum);
}
return 0;
}
2017.11.17 新手上路 请多指教。。。
以上是关于贪心练习 hdu1789的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1789 Doing Homework again(贪心)
hdu 1789 Doing Homework again 贪心