0x07 贪心
被虐爆了。。。贪心这种玄学东西还可以证吗??除了范围缩放算是可以想想比较经典(倍增第一题?)。。。
poj3614:这道题想了很久,并没有想到是把minSPF按大到小排序,一直的思想是小的就小到大排序。后来仔细分析下,这题做法是n^2的,假如排序是要控制一个值的单调性,再用一个for来贪心,假如是小到大排序,选取时应该取大的还是应该取小的?直观上想选小的,因为后面的下界大,但是,假如当前位置区间很大而后一个很小就出问题了。假如是大到小排序,相当于逆过来,此时尽量取大,是基于当前的上界的,对于下界已经没有必要关注了,因为是单调递减的。考虑到这题没有权值,也可以看作全为1,当前的最大和后面的匹配无法得到更优解。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y;
}a[],b[];
bool cmp(node n1,node n2){return n1.x>n2.x;}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
for(int i=;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y);
sort(a+,a+n+,cmp);
sort(b+,b+m+,cmp); int ans=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
if(a[i].x<=b[j].x&&b[j].x<=a[i].y&&b[j].y>)
{
b[j].y--;ans++;
break;
}
}
printf("%d\n",ans);
return ;
}
poj3614
poj3190:这题倒是没什么。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std; struct node
{
int x,y,z;
friend bool operator>(node q1,node q2){return q1.y>q2.y;}
}a[];priority_queue< int,vector<node>,greater<node> >q;
bool cmp(node n1,node n2){return n1.x<n2.x;} int bel[];
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y), a[i].z=i;
sort(a+,a+n+,cmp); int ans=;q.push(a[]);bel[a[].z]=;
for(int i=;i<=n;i++)
{
node t=q.top();
if(t.y<a[i].x)q.pop(),bel[a[i].z]=bel[t.z];
else ans++,bel[a[i].z]=ans;
q.push(a[i]);
}
printf("%d\n",ans);
for(int i=;i<=n;i++)printf("%d\n",bel[i]);
return ;
}
poj3190
poj1328:也算是小小的套路题吧。在越后放越好,“决策包容性”虽然运用的不是挺灵活,但是还蛮好想(所以这题难度在转换问题变成在n个区间里都要有至少一个点??)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
double l,r;
}a[];
bool cmp(node n1,node n2)
{
if(fabs(n1.l-n2.l)<1e-)return n1.r<n2.r;
return n1.l<n2.l;
} bool v[];
int main()
{
int n,T_T=;double R;
while(scanf("%d%lf",&n,&R)!=EOF)
{
if(n==&&R==)break;
T_T++; double x,y;bool bk=true;
for(int i=;i<=n;i++)
{
scanf("%lf%lf",&x,&y);
if(y>R)bk=false;
double dis=(sqrt((R*R)-(y*y)));
a[i].l=x-dis;a[i].r=x+dis;
}
if(bk==false){printf("Case %d: -1\n",T_T);continue;}
sort(a+,a+n+,cmp); int ans=;
memset(v,false,sizeof(v));
for(int i=;i<=n;i++)
{
if(v[i]==false)
{
ans++;v[i]=true;double pos=a[i].r;
for(int j=i+;j<=n;j++)
if(a[j].l<=pos)v[j]=true,pos=min(pos,a[j].r);
else break;
}
}
printf("Case %d: %d\n",T_T,ans);
}
return ;
}
poj1328
upd:我之前写的实在是太不优秀了。
把区间弄出来以后,相当于用最小的点覆盖所有区间,那么对于区间相互包含,不用管,对于区间分开没有交集,直接新开
那么就要处理覆盖一部分的情况。按L排序,决策包容,能选就选,L区间单调增,维护个R单调减,非法就新开
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node{double L,R;}a[];
bool cmp(node n1,node n2){return n1.L<n2.L;}
int main()
{
int n,T_T=; double m,x,y;
while(scanf("%d%lf",&n,&m)!=EOF)
{
if(n==&&m==)break; bool bk=true;
for(int i=;i<=n;i++)
{
scanf("%lf%lf",&x,&y);
if(y>m)bk=false;
a[i].L=x-sqrt(m*m-y*y);
a[i].R=x+sqrt(m*m-y*y);
}
if(bk==false){printf("Case %d: -1\n",++T_T);continue;}
sort(a+,a+n+,cmp); int ans=;double R=a[].R;
for(int i=;i<=n;i++)
{
if(a[i].L>R)
ans++, R=a[i].R;
else
R=min(R,a[i].R);
}
printf("Case %d: %d\n",++T_T,ans);
}
return ;
}
poj1328(upd)
NOIP2012国王游戏:完全没有见过这种题型。。书上说微扰这个东西经常用于以排序为贪心策略的问题?反正这种数学东西证明,假如想到的话一般的还是不难推的。
顺便安利一道题bzoj3174: [Tjoi2013]拯救小矮人
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; int n,m;LL k;
LL a[],b[],tt[];
void mergesort(int l,int r)
{
if(l==r)return ;
int mid=(l+r)/;
mergesort(l,mid);mergesort(mid+,r); int i=l,j=mid+,p=l;
while(i<=mid&&j<=r)
{
if(b[i]<=b[j])tt[p++]=b[i++];
else tt[p++]=b[j++];
}
while(i<=mid)tt[p++]=b[i++];
while(j<=r) tt[p++]=b[j++]; for(int i=l;i<=r;i++)b[i]=tt[i];
}
int clen;LL c[];
bool check(int l,int r)
{
if(r>n)return false; int blen=r-l+;
for(int i=l;i<=r;i++)b[i-l+]=a[i];
mergesort(,blen); int i=,j=,p=;
while(i<=blen&&j<=clen)
{
if(b[i]<=c[j])tt[p++]=b[i++];
else tt[p++]=c[j++];
}
while(i<=blen)tt[p++]=b[i++];
while(j<=clen)tt[p++]=c[j++]; p--;
LL sum=;
for(int i=;i<=m;i++)
{
if(p-i+<=i)break;
sum+=(tt[p-i+]-tt[i])*(tt[p-i+]-tt[i]);
} if(sum<=k)
{
clen=p;
for(int i=;i<=clen;i++)c[i]=tt[i];
return true;
}
else return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%lld",&n,&m,&k);
for(int i=;i<=n;i++)scanf("%lld",&a[i]); int ed,ans=;
for(int st=;st<=n;st=ed+)
{
ed=st;int L=;
clen=;c[++clen]=a[st];
while(L>)
{
if(check(ed+,ed+L)==true)
{
ed=ed+L;
L*=;
}
else L/=;
}
ans++;
}
printf("%d\n",ans);
}
return ;
}
NOIP2012国王游戏
poj2054:这题是真的难啊,大开眼界。。。有一个性质,树中除根以外的最大点,一定会在它的父亲被染色之后被染色,那么居然依此来合并点。此时我们的目标是先把染色顺序给弄好,选择了放弃原本的权值转而自己定义新的权值!定义为合并包含的所有点的权值平均值。是可以数学归纳法证明的(这个东西不太会啊,我只用过来证柯西不等式。。。)具体做法我就是用链表存储顺序,然后用一个并查集维护合并了的块。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; int F[];
int findfa(int x)
{
if(F[x]==x)return x;
F[x]=findfa(F[x]);return F[x];
}
int u[],fa[];
struct node{int d,z;}c[];
bool v[];
int bef[],aft[],la[];
int main()
{
int n,R;
while(scanf("%d%d",&n,&R)!=EOF)
{
if(n==&&R==)break; for(int i=;i<=n;i++)
{
scanf("%d",&c[i].d);u[i]=c[i].d;
c[i].z=;F[i]=i;
bef[i]=aft[i]=-;la[i]=i;
}
int x,y;
for(int i=;i<n;i++)
scanf("%d%d",&x,&y), fa[y]=x; memset(v,false,sizeof(v));v[R]=true;
for(int i=;i<n;i++)
{
int id=-;
for(int j=;j<=n;j++)
if(v[j]==false)
if(id==-||c[id].d*c[j].z<c[j].d*c[id].z)id=j; v[id]=true;
int truefa=findfa(fa[id]);F[id]=truefa;
c[truefa].d+=c[id].d;
c[truefa].z+=c[id].z; bef[id]=la[truefa];
aft[la[truefa]]=id;
la[truefa]=la[id];
} LL ans=;
for(int i=;i<=n;i++)
ans+=(LL(i))*(LL(u[R])), R=aft[R];
printf("%lld\n",ans);
}
return ;
}
poj2054
0x07 贪心的更多相关文章
- 算法竞赛进阶指南 0x00 基本算法
放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...
- 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 ...
随机推荐
- @synthesize和@dynamic区别
在声明property属性后,有2种实现选择 @synthesize 编译器期间,让编译器自动生成getter/setter方法. 当有自定义的存或取方法时,自定义会屏蔽自动生成该方法 @dynami ...
- 如果碰到git提示“ignored tracked with git”,那么使用以下命令解决
命令:git rm --cached -r 文件/文件夹 问题在初始化git仓库的时候没有创建.gitignore文件来过滤不必要提交的文件, 后来却发现某些文件不需要提交, 但是这些文件已经被提交了 ...
- WPF全球化与本地化
当一个App需要推出多语言版本时,就需要使用到[全球化与本地化]服务. 原理及过程 资源文件中包含了所有的控件信息,通过导出这些控件信息,修改其对应的相关属性(比如TextBlock的Text属性)的 ...
- cropper+pillow处理上传图片剪裁(二)
上次说到处理上传头像的方法是临时保存在本地,其实这样做并不妥,而且修改后的头像重新上传到model中也很麻烦,差了很多资料,解决了这个问题 大致思路:用户上传原图和修改数据—PIL修改后将图片保存为内 ...
- arttemplate.js简洁写法案例
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 读书笔记「Python编程:从入门到实践」_3.列表简介
3.1 列表是什么 列表 由一系列按特定顺序排列的元素组成. 在Python中,用方括号([] )来表示列表,并用逗号来分隔其中的元素. 3.1.1 访问列表元素 指出列表的名称,再指出元素的索引 ...
- 京东专业“卖”队友,魅族手环将亮相1206魅蓝note新品发布会
京东一直是国内顶级的数码产品自营销售渠道,但是,正因为庞大的数据体系和平台特殊性,经常会帮我们发现一些“好玩的”保密性较高的东西,譬如价格.信息.谍照等.而在最新上线的京东超级品牌日活动页面上,专业“ ...
- CorelDRAW X7中相机滤镜呈现出的复古照片效果
CorelDRAW X7软件中相机效果滤镜较之以前版本又增添了许多功能,模拟各种“相机”镜头产生的效果,包括彩色.相片过滤器.棕褐色色调和时间器效果,可以让照片回到历史,展示过去流行的摄影风格.以下步 ...
- 使用DOS命令查找包含某一字符串的所有文件
在windows系统下,来查找并修改指定目录下包含某一字符串的所有文件,麻烦又费时.其实在DOS命令中,提供了Findstr命令来查找指定的一个或多个文件文件中包含(或通过参数 /V来控制不包含) ...
- hibernate增删改查总结
hibernate操作的都是基于对象的(曾save删delete改update) 进行hql查询是设置参数从零开始(session.setParameter(0,#)) hql查询设置参数可以是其他( ...