s 贪心
区间问题:
区间选点问题 右端点排序,now标记点。
数轴上有N个闭区间[Ai, Bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。
输入
第1行:一个整数N(1 <= N <=100000)
接下来N行,每行2个整数Ai,Bi(-10^7 <= Ai < Bi < 10^7)
输出
第1行:一个整数,表示满足条件的最少点数。
#include <bits/stdc++.h>
using namespace std;
const int N =;
#define ri register int
struct dian{
int l,r;
bool operator <(const dian &t)const
{
if(r==t.r) return l>t.l;
return r<t.r;
}
}p[N];
int n,m,cent;
int main(){
scanf("%d",&n);
for(ri i=;i<=n;i++) scanf("%d%d",&p[i].l,&p[i].r);
sort(p+,p++n);
for(ri i=;i<=n;i++)
cent=; int now=p[].r;
for(ri i=;i<=n;i++)
{
if(p[i].l>now)
cent++,now=p[i].r;
}
printf("%d\n",cent);
}
区间覆盖问题
数轴上有N个闭区间[Ai, Bi],选择尽量少的区间覆盖一条指定线段[S, T]。
题解:(1)找到所有的、起点小于s的区间
(2)把这些区间按照起点,从小到大排序
(3)选择终点最大的那个区间,设这个最大的终点是bi
(4)现在问题变成了,“选择尽量少的区间覆盖一条指定线段[bi, t]
输入
第1行:先是一个整数N(1 <= N <=10^6),然后是两个整数S和T(-10^7 <= S < T <= 10^7)
接下来N行,每行2个整数Ai,Bi(-10^7 <= Ai < Bi < 10^7)
输出
第1行:一个整数,表示最少需要的区间的个数。如果无解,输出 No Solution
#include <bits/stdc++.h>
using namespace std;
const int N =;
const int M =;
#define ri register int
struct dian{
int l,r;
bool operator <(const dian &t)const
{
if(l==t.l) return r<t.r;
return l<t.l;
}
}p[N];
int n,s,e;
int main(){
scanf("%d%d%d",&n,&s,&e);
int now=s;int cent=;
for(ri i=;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a>e||b<s) continue;
p[++cent].l=a,p[cent].r=b;
}
sort(p+,p++cent);
int i=,num=;
while(now<e)
{
int k=now;
for(;p[i].l<=k&&i<=cent;i++)
{
now=max(now,p[i].r);
}
num++;
if(now==k) {printf("No Solution");return ;}
}
printf("%d",num);
}
区间划分集合问题
题目 时间轴上有n个开区间(ai, bi),把这些区间至少划分成多少个集合,使得每个集合中的区间两两没有公共点。因为是开区间,所以(1, 2)和(2,3)可在一个集合中。
题 解 先将所有区间按左端点排序排序。 用一个数组来存当前每个已知集合最右的端点。若没有任何集合左端点比此区间小,就增加一个集合。 若有,就取可行集合中最大 的右端点所在集合,并更新。
输入
第1行:一个整数N(1 <= N <=10^5)
接下来N行,每行2个整数Ai,Bi(0<= Ai < Bi < 10^7)
输出
第1行:1个整数,需要划分成的最少集合数。
#include <bits/stdc++.h>
using namespace std;
const int M =;
const int N =;
#define ri register int
struct dian{
int l,r;
bool operator <(const dian &t)const
{
if(l==t.l) return r>t.r;
return l<t.l;
}
}p[N];
int n,m,f[N],k[N];
int main(){
scanf("%d",&n);
for(ri i=;i<=n;i++) scanf("%d%d",&p[i].l,&p[i].r);
sort(p+,p++n);
k[]=p[].r;
int cent=;
for(ri i=;i<=n;i++)
{
int flag=;
for(ri j=;j<=cent;j++)
{
if(p[i].l>k[j]) flag=,k[j]=p[i].r;
}
if(!flag) k[++cent]=p[i].r;
}
printf("%d",cent);
}
总结 : 区间问题先排序,在具体分析,(排序后少了个限制条件)
流水线问题:
题解 :
(1)把在A车间加工时间最短的部件最先加工,这样使得B车间能更快开始加工。
(2)把在B车间加工时间最短的部件最后加工,这样使得A车间的空闲时间最短。(反正B一定要A先加工,A多加工出来的继续加工下一个就行了)
题目描述
某工厂收到了n个产品的
订单,这n个产品分别在A、B两个车间加工,并且必须先在A车间加工后才可以到B车间加工。
某个产品i在A、B两车间加工的时间分别为Ai、Bi。怎样安排这n个产品的加工顺序,才能使总的加工时间最短。这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在A、B两车间加工完毕的时间。
输入格式
第一行仅—个数据n(0<n<1000),表示产品的数量。
接下来n个数据是表示这n个产品在A车间加工各自所要的时间(都是整数)。
最后的n个数据是表示这n个产品在B车间加工各自所要的时间(都是整数)。
输出格式
第一行一个数据,表示最少的加工时间;
第二行是一种最小加工时间的加工顺序。
输入输出样例
5
3 5 8 7 10
6 2 1 4 9
34
1 5 4 2 3
#include <bits/stdc++.h>
using namespace std;
const int M =;
#define ri register int
int a[M],b[M],c[M];
long long t[M];
struct dian{
int id,cost;
}p[M];
bool cmp(dian a,dian b)
{
return a.cost<b.cost;
}
int n,ans[M];
int main(){
scanf("%d",&n);
for(ri i=;i<=n;i++) scanf("%d%d",&a[i],&b[i]) ,p[i].cost=min(a[i],b[i]),p[i].id=i;
sort(p+,p++n,cmp);
int s=,e=n+;
for(ri i=;i<=n;i++)
{
if(p[i].cost==a[p[i].id])
ans[++s]=p[i].id;
else ans[--e]=p[i].id;
}
for(ri i=;i<=n;i++) t[i]=t[i-]+a[ans[i]];
long long sum=t[]+b[ans[]];
for(ri i=;i<=n;i++)
sum=max(sum,t[i])+b[ans[i]];
printf("%lld",sum);
}
矩阵问题:
进行压缩,多行压缩成一行(多维转一唯)
题目:
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,求最大非空子矩阵。 例如: - - - - - - - 最大子矩阵是: - - 输入 两行:
第一行n
然后n行,每行n个数,
代表一个n*n的矩阵。 输出 最大子矩阵 样例输入 Copy - -
-
- -
- -
样例输出 Copy
最大矩阵
代码:
#include <bits/stdc++.h>
using namespace std;
const int M =;
#define ri register int
int arr[M][M],b[M];
int maxla(int a[],int n)
{
int sum=a[],ans=a[];
for(ri i=;i<=n;i++)
{
if(sum+a[i]>a[i]) sum+=a[i];
else sum=a[i];
if(sum>ans)
ans=sum;
}
return ans;
}
int n;
int main(){
scanf("%d",&n);
int ans=-;
for(ri i=;i<=n;i++)
for(ri j=;j<=n;j++)
scanf("%d",&arr[i][j]);
for(ri i=;i<=n;i++)
{
for(ri j=;j<=n;j++)
b[j]=;
for(ri j=i;j<=n;j++)
{
for(ri k=;k<=n;k++)
{
b[k]+=arr[j][k];
}
int sum=maxla(b,n);
ans=max(sum,ans);
}
}
printf("%d",ans);
}
单位 罚款 问题
方法 和之前 一个 类似 优先队列 搞一搞
题目
问题 O: 不守交规
时间限制: Sec 内存限制: MB 题目描述
近些年来,生活水平越来越好,私家车也成了很多家庭必备之物。但某些司机总是不守交规,罚单也是接踵而至。 有一位不遵守交规的司机,在同一天收到了n条违章罚单短信(≤n≤),每条罚单短信中有两个内容,一:交罚款的最后剩余时间ti;二:过期未交的滞纳金mi(≤ti,mi≤),假设不管过期多少天,滞纳金数量不会改变,而且,这位司机很忙,每天最多只能处理一张罚单,那么,这位司机应该按怎样的处理违章短信的顺序,才能使滞纳金总和最少? 输入
共n+1行
第1行:收到短信数n
后n行:每行分别两个数,最后期限ti和过期滞纳金mi,用空格隔开
输出
最少的滞纳金总和
样例输入 Copy 样例输出 Copy
代码:
// 14 36
#include <bits/stdc++.h>
using namespace std;
const int M =;
#define ri register int
struct dian{
int cost,ed;
bool operator <(const dian &k)const
{
return ed<k.ed;
}
}p[M];
int n;
struct cmp{
bool operator ()( int &a, int &b)
{
return a>b;
}
};
priority_queue <int,vector<int>,cmp> q;
int main(){
scanf("%d",&n);
for(ri i=;i<=n;i++)
scanf("%d",&p[i].ed);
for(ri i=;i<=n;i++)
scanf("%d",&p[i].cost);
sort(p+,p++n);
int trmp=,ans=;
for(ri i=;i<=n;i++)
{
if(trmp+<=p[i].ed)
q.push(p[i].cost),trmp++;
else if(trmp<=p[i].ed&&q.top()<p[i].cost)
ans+=q.top(),q.pop(),q.push(p[i].cost);
else ans+=p[i].cost;
}
cout<<ans;
}
反向思考:
题目
问题 P: 【USACO TRAINING】修理牛棚
时间限制: Sec 内存限制: MB
题目描述
在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 剩下的牛一个紧挨着另一个被排成一行来过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。
在门被吹飞以后,农民约翰必须尽快在牛棚之前竖立起新的木板。 他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。
给出可能买到的木板最大的数目 M(<= M<=),牛棚的总数S(<= S<=),牛棚里牛的数目C( <= C <=S) 和牛所在的牛棚的编号( <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。
输出所需木板的最小总长度作为的答案。
输入
第1行:3个整数 M,S和C
第2..C+1行:每行一个整数,表示牛所占的牛棚的编号。
输出
第1行:一个整数,表示所需木板的最小总长度。
样例输入 Copy 样例输出 Copy
代码:
#include <bits/stdc++.h>
using namespace std;
const int M =;
#define ri register int
int a[M],b[M];
int n,x,c;
int cmp(int a,int b)
{
return a>b;
}
int main(){
scanf("%d%d%d",&n,&x,&c);
if(n>=c)
{
printf("%d",c);return ;}
for(ri i=;i<=c;i++)
scanf("%d",&a[i]);
sort(a+,a++c);
int ans=a[c]-a[]+;
for(ri i=;i<=c;i++)
b[i-]=a[i]-a[i-];
sort(b+,b+c,cmp);
for(ri i=;i<n;i++)
{
ans-=b[i];
}
printf("%d",ans+n-);
}
1
数学类型的贪心: 结合公式? 前后比较?
题目
题意: 现在有n个人,有两个问题x,y 每个人对应有一个xi yi 表示解决这道题的分数,当然这里也有一些关系,u v 表示u v 不能组成一组做题,那么问你每个人和其他所有能组队的人做这两道题的最小分数是多少。也就是问你对于当前的 xi yi 所有能组队的j min(xi+yj,yi+xj) 的最小值的和。
代码
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M =;
const int N =;
typedef long long ll;
#define ri register int
int n,m;
ll x[N],y[N],ans[N],a[N],sum;
bool cmp(int aa,int bb)
{
if(x[aa]-y[aa]<x[bb]-y[bb]) return ;
return ;
}
int head[N],cent;
struct setbian{
int net,to;
}bian[M];
void add(int a,int b)
{
bian[++cent].net=head[a],head[a]=cent;
bian[cent].to=b;
}
int main(){
scanf("%d%d",&n,&m);
for(ri i=;i<=n;i++)
{
scanf("%lld%lld",&x[i],&y[i]);
a[i]=i;
}
for(ri i=;i<=m;i++)
{
int aa,bb;
scanf("%d%d",&aa,&bb);
add(aa,bb);add(bb,aa);
}
sort(a+,a++n,cmp);
for(ri i=;i<=n;i++)
{
int id=a[i];
ans[id]+=sum+(i-)*y[id];
sum+=x[id];
}
sum=;
for(ri i=n;i>=;i--)
{
int id=a[i];
ans[id]+=sum+(n-i)*x[id];
sum+=y[id];
}
for(ri i=;i<=n;i++)
for(ri j=head[i];j;j=bian[j].net)
{
int v=bian[j].to;
ans[i]-=min(x[i]+y[v],y[i]+x[v]);
}
for(ri i=;i<=n;i++)
printf("%lld ",ans[i]);
}
的
s 贪心的更多相关文章
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- HDOJ 1051. Wooden Sticks 贪心 结构体排序
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDOJ 1009. Fat Mouse' Trade 贪心 结构体排序
FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]
1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 786 Solved: 391[Submit][S ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【BZOJ-4245】OR-XOR 按位贪心
4245: [ONTAK2015]OR-XOR Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 486 Solved: 266[Submit][Sta ...
- code vs 1098 均分纸牌(贪心)
1098 均分纸牌 2002年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有 N 堆纸牌 ...
- 【BZOJ1623】 [Usaco2008 Open]Cow Cars 奶牛飞车 贪心
SB贪心,一开始还想着用二分,看了眼黄学长的blog,发现自己SB了... 最小道路=已选取的奶牛/道路总数. #include <iostream> #include <cstdi ...
- 【贪心】HDU 1257
HDU 1257 最少拦截系统 题意:中文题不解释. 思路:网上有说贪心有说DP,想法就是开一个数组存每个拦截系统当前最高能拦截的导弹高度.输入每个导弹高度的时候就开始处理,遍历每一个拦截系统,一旦最 ...
- hdu 2037简单贪心--活动安排问题
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...
随机推荐
- 【Git】git使用 - 冲突conflict的解决演示
冲突的解决 (如果git使用不熟练)建议在push不了时,pull之前.在本地创建一个新的分支并commit到local,以保证本地有commit记录,万一出什么问题,可以找回代码,以免代码丢失. ( ...
- maven的核心概念——坐标
7.1 几何中的坐标 [1]在一个平面中使用x.y两个向量可以唯一的确定平面中的一个点. [2]在空间中使用x.y.z三个向量可以唯一的确定空间中的一个点. 7.2 Maven的坐标 使用如下三个向量 ...
- 星星评分-依赖jquery
https://pan.baidu.com/s/1UWJFh-QJOjSB_yqA8VgHIQ
- 10、初识constexpr和常量表达式
常量表达式:是指值不会改变并且在编译过程就能得到计算结果的表达式.显然字面值属于常量表达式,用于表达式初始化的const对象也是常量表达式. 1.判断一个变量是不是常量表达式 一个对象(表达式)是不是 ...
- IDA PRO
链接:https://pan.baidu.com/s/1LTXhXra5Honpn3L9rfSOgA 提取码:7bwb 工具下载地址: https://www.jb51.net/softjc/5799 ...
- BundlePhobia
1.BundlePhobia用于分析npm package的依赖.bundle后的大小.下载速度预估等等,帮助你在引用一个package之前了解引入该package的代价. 2.也可以将项目的pack ...
- 3个N加上各种运算符号结果等于6(纯属娱乐)C#
网上的题目: 题有点难 但都有解 2 2 2 = 6 3 3 3 = 6 4 4 4 = 6 5 5 5 = 6 6 6 ...
- 【spring】jdbcTemplate之sql参数注入
demo @Repository("jdbcDao") public class JdbcTemplateDao { @Autowired private JdbcTemplate ...
- Java第二节课总结
Java的基本运行单位是类.类由数据成员和函数成员组成.变量的类型之间可以相互转换.String是一个类.static代表静态变量. 运行结果: false false ...
- 在eclipse更新启动项目
说明:figfree是基于模块化开发,代码重用,可拆解性高. 功能模块分为:接口工程(*.Iface).接口实现工程(*.Impl).客户端工程(*.Client) 接口工程(*.Iface):对其他 ...