基本概念
首先,贪心只是一种思想,没有固定的算法可用。它的主要思路就是对于一个大的问题在寻求最优解时,将其分解为若干个子问题,再寻找每一个子问题的最优解。有时候子问题是大的问题的一个阶段,有时是一个部分,所以思考的时候注意切入点,另外,贪心思想产生了若干子问题,思考算法时注意复杂度,不要超时。
CSU 1588
现在有n堆果子,第i堆有ai个果子。现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数。求合并所有果子的最小代价。
Input
第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个整数n(2<=n<=1000),表示果子的堆数。
第二行包含n个正整数ai(ai<=100),表示每堆果子的果子数。**
Output
每组数据仅一行,表示最小合并代价。
Sample Input
2
4
1 2 3 4
5
3 5 2 1 4
Sample Output
19
33
Hint
题目要求把果子合并成一个,即每次都会合并两个直到只剩一个为止。那么思考得出的子问题就是,每次合并都要寻求最小代价。使用sort函数来多次寻找最小值即可。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int t,n,a[1005],i,e;
scanf("%d",&t);
while(t--)
{
e=0;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n-1;i++)
{
sort(a+i,a+n);
a[i+1]=a[i]+a[i+1];
e=e+a[i+1];
}
printf("%d\n",e);
}
}
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
Hint
题目大意:小明写作业,每份作业都有各自的deadline,超过deadline会有不同的惩罚,而且小明一天只能写一份作业,所以问如何安排写作业的顺序,使小明被惩罚的力度最小。
惩罚力度有大有小,那么将其按降序排序,从最大的日期向前推,每天都去解决当日仍存的最大惩罚力度的作业,那么子问题就是每天处理哪一份作业了。由于每份作业都有绑定的deadline和惩罚力度,所以构建结构体会方便一点。
#include<stdio.h>
#include<algorithm>
using namespace std;
struct ss
{
int score;
int time;
bool operator< (const ss & b)const
{
return (score > b.score);
}//重载“<”,使得结构体与sort可以结合使用
}b[1005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a[1005];
int i,j,e=0;
for(i=0;i<1005;i++)
a[i]=0;
int n;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&b[i].time);
for(i=0;i<n;i++)
scanf("%d",&b[i].score);
sort(b,b+n);//降序排序
for(i=0;i<n;i++)
{
for(j=b[i].time;j>0;j--)//从截止日期向前推
if(a[j]==0)//有空的日期就标记为非空,然后跳出
{
a[j]=1;
break;
}
if(j==0) e=e+b[i].score;//找不到就加上相应的分值
}
printf("%d\n",e);
}
}
HDU 1789
Emily the entrepreneur has a cool business idea: packaging and selling snowflakes. She has devised amachine that captures snowflakes as they fall, and serializes them into a stream of snowflakes that flow,one by one, into a package. Once the package is full, it is closed and shipped to be sold.The marketing motto for the company is “bags of uniqueness.” To live up to the motto, everysnowflake in a package must be different from the others.
Unfortunately, this is easier said than done,because in reality, many of the snowflakes flowing through the machine are identical. Emily would liketo know the size of the largest possible package of unique snowflakes that can be created. The machinecan start filling the package at any time, but once it starts, all snowflakes flowing from the machinemust go into the package until the package is completed and sealed. The package can be completed and sealed before all of the snowflakes have flowed out of the machine.
Input
The first line of input contains one integer specifying the number of test cases to follow. Each testcase begins with a line containing an integer n, the number of snowflakes processed by the machine.
The following n lines each contain an integer (in the range 0 to 10^9, inclusive) uniquely identifying asnowflake. Two snowflakes are identified by the same integer if and only if they are identical.
The input will contain no more than one million total snowflakes.
Output
For each test case output a line containing single integer, the maximum number of unique snowflakes that can be in a package.
Sample Input
1
5
1
2
3
2
1
Sample Output
3
Hint
题目大意:小红开了一家工厂,按袋卖雪花,她的卖点就是她的雪花是独一无二的(意思是每袋里的雪花各自都不一样,就像一袋彩虹糖,里面的糖的味道都不一样),但是机子比较菜(像博主一样),只会按顺序包装雪花。然后问能包装出的雪花袋最多有多少雪花。
我们可以做一个滑动窗口,由于题目的数值比较大,所以注意算法不要太复杂。
#include<stdio.h>
#include<iostream>
#include<set>
#define maxn 1000005
int a[maxn];
using namespace std;
int main()
{
int t,s,max;
scanf("%d",&t);
while(t--)
{
max=0;
int i,n,e=1,c,l=0,r=0;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
set<int> s(a,a+1);//直接定义出现了莫名的bug,所以就先塞了一个元素,再清空
s.clear();
while(r<n)
{
while(r<n&&!s.count(a[r])) s.insert(a[r++]);//如果没遇到相同的元素,右边窗口不断向右移动
if(r-l>e) e=r-l;
s.erase(a[l++]) ;//遇到相同元素,左侧的元素被依次清除,直到除掉那个相同元素为止
}
printf("%d\n",e);
}
return 0;
}