看过的题目整理:
贪心专题:
1.题目:已知人的重量,船的最大载重量,问最少几只船。
方法:贪心思想
简单说下思路:先把n人重量递减排序,从排序后的第一人(最重的人)开始判定,如果体重等于最大载重量,直接船数加一;否则让他与最后一人(最轻的人)体重相加,如果总体重小于或等于最大载重,把最后一人去掉(n--),船数加一,如果大于最大载重船数加一再返回,然后继续第二人判定。
https://blog.csdn.net/chenzhenyu123456/article/details/42121827
2.题目:在n个数中删除m个数字,使得余下的数字按原次序组成的新数最大
比如当n=92081346718538,m=10时,则新的最大数是9888
思路:本题转化思想,就是找(n-m)个数,使得和尽量大
寻找l-m个最大值,当然找第一个时千万要记着从第0项到第l-m项(举个数自己好好想,想明白就会了),找到第一个最大值s[i]输出之后,接下来只需从i+1开始(题目要求按次序)找下一个最大值(和找第一个一样,记着不是简单的找到最后一项),找够l-m即可。
3.题目:给了一些闭区间,要求找最少的n个点,使得n个区间内都至少包含一个点。
思路:对给定闭区间按照左端点递增进行排序,进行:for(i=0;i<n;i++){if(num[i].start>max) { max=num[i].end; sum++; }} 操作。具体细节自己体会。
https://blog.csdn.net/chenzhenyu123456/article/details/42556763
4.寻找最大数
题目:
给出一个整数N,每次可以移动2个相邻数位上的数字,最多移动K次,得到一个新的整数。
求这个新的整数的最大值是多少
思路:方法跟之前的类似,主要是在前k位中找到一个最大值,然后再从最大值的这个位置依次往后找最大的。。。
贪心算法,但是对每一步进行贪心,应该是在k步的范围内找到最大的值,往前依次交换,如果找到了最大的值,但是没有到k步,那么对接下来的kk步继续从当前最优往后寻找。
代码:https://blog.csdn.net/chenzhenyu123456/article/details/42685759
5.做作业问题
题意:给定做不完作业扣的分数,和收作业的截止时间,问最优的策略是什么。
思路:
代码:https://blog.csdn.net/chenzhenyu123456/article/details/43803567
6.外星人的供给站
代码:
思路:先将Pi按x坐标从小到大排序。然后求出能包含Pi的极光点的x坐标区间【left<=x<=right】。在求下一个能包含P(i+1)的极光点坐标区间,如果与上一个区间有公共区间的话说明这两个点可以被同一个圆包含
代码:https://blog.csdn.net/z956281507/article/details/69055666
7.题目:给定原始序列a[i]={0},每次变化时任取i~n,可以同时add1或sub1,问最少多少次使得变成b[i]
代码:for(int i = 1; i <= n; i++) { Rl(a[i]); ans += abs(a[i] - a[i-1]); }
https://blog.csdn.net/chenzhenyu123456/article/details/49888019
8.题目:给定n个人的到达时间和离开时间,问最多可以接待多少人。
思路:按照结尾时间进行排序,直接模拟贪心即可。
9.题目:rader installation
给定n个点,还有雷达的范围半径d,雷达只能建在x轴上,问最少安装几个雷达使得所有点全覆盖
思路:这是一道区间覆盖的题目。认真想一下,雷达想要覆盖点i,那么就找雷达最左,最右的位置,就是
最左为:x - sqrt(d*d-y*y); 最右为:x - sqrt(d*d-y*y); 然后就在这之间进行移动就可。然后要做的就是去见排序,然后循环统计几个区间是互相覆盖的。
代码:https://blog.csdn.net/chenzhenyu123456/article/details/47169805
10.Huffman树的构造问题
题目大意:
有一个农夫要把一个木板钜成几块给定长度的小木板,每锯一次都要收取一定费用,这个费用就是当前锯掉的木板长度
给出n个木板及其各自的长度,求最小费用。
思路:利用haffman树。huffman:ans记录最小花费,每次取队列里最小的两个值,出队后,ans累加两个数的和,再将两数之和进队列,直到队列只有1个元素为止。最后的ans就是最小花费。
代码:
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#define MAX 20000+10
#define LL long long
using namespace std;
int a[MAX];
LL ans;//最小花费
priority_queue<LL, vector<LL>, greater<LL> > Q;//小的优先
void huffman()
{
LL a, b, c;//这里坑死了
while(Q.size() != 1)//只有一个元素为止
{
a = Q.top();//取最小的值
Q.pop();
b = Q.top();//取最小的值
Q.pop();
c = a + b;//求和
ans += c;//结果累加
Q.push(c);//进队列
}
Q.pop();
}
int main()
{
int n;//木板个数
int i, j;
while(scanf("%d", &n) != EOF)
{
for(i = 0; i < n; i++)
{
scanf("%d", &a[i]);
Q.push(a[i]);//进队列
}
ans = 0;
huffman();
printf("%lld\n", ans);
}
return 0;
}
11.土豪银行
题目大意:1, P,P^2, P^3, P^4 ...面额的纸币,问最少给多少张钱使得面额等于Q
思路:还是从贪心,要注意细节优化。
代码: for(i=14;i>=0;i--)//2的14次方已经大于10000
{ if(have==Q) break; while(have+pow(P,i)<=Q){need++;have+=pow(P,i);}}
https://blog.csdn.net/chenzhenyu123456/article/details/45081619