1.P1230智力大冲浪
思路:赢取最多的钱,即扣掉的钱最少。等价于m先减去所有的wi,再计算最大得分。对于时段x我们可以做时限ti>=x的游戏。所以从后往前枚举时段i,把时限ti>=i的游戏的wi放入一个大根堆,每一时段m加上堆顶值。注意中间可能空堆。
const int maxn=505;
struct node{int t,w;}e[maxn];
bool cmp(node a,node b){return a.t<b.t;}
priority_queue<int>q;
int main(){
int m=read(),n=read(),maxx=0;
for(int i=1;i<=n;i++)e[i].t=read(),maxx=max(maxx,e[i].t);
for(int i=1;i<=n;i++)e[i].w=read(),m-=e[i].w,q.push(0);
sort(e+1,e+1+n,cmp);int now=n;
for(int i=maxx;i>=1;i--){
while(e[now].t>=i)q.push(e[now].w),now--;
m+=q.top();q.pop();
}
if(m<0)printf("0
");
else printf("%d
",m);
return 0;
}
2.整数区间
我们定义一个整数区间[a,b]:是一个从a开始至b结束的连续整数的集合。
编一个程序,对给定的 n(n≤1000)个区间,找出满足下述条件的所含元素个数最少的集合中元素的个数:对于所给定的每一个区间,都至少有两个不同的整数属于该集合。
解法1:差分约束。之前写过了。
解法2:题意即从每个区间选至少两个点,使选点总数最小。按照左端点从大到小枚举区间,则若此区间没选满两个点,优先选择靠左的点一定最优。
const int maxn=10005;
struct node{int l,r;}a[maxn];
bool cmp(node a,node b){return a.l>b.l;}
int vis[maxn],ans;
int main(){
int n=read();
for(int i=1;i<=n;i++)a[i].l=read(),a[i].r=read();
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
int tot=0;
for(int j=a[i].l;j<=a[i].r;j++)
if(vis[j])tot++;
if(tot==0)ans+=2,vis[a[i].l]=vis[a[i].l+1]=1;
else if(tot==1)ans++,vis[a[i].l]=1;
}
printf("%d
",ans);
return 0;
}
3.活动选择
线段覆盖板子,按右端点排序,能选的优先选右端点较小的。
const int maxn=1005;
struct node{
int l,r;
}p[maxn];
bool cmp(node a,node b){
if(a.r==b.r)return a.l>b.l;
return a.r<b.r;
}
int main(){
int k=read(),cnt=0,tmp=0;
for(int i=1;i<=k;i++){
//int a=read();
p[i].l=read();
p[i].r=read();
}
sort(p+1,p+1+k,cmp);
for(int i=1;i<=k;++i){
if(p[i].l>=tmp){
cnt++;
tmp=p[i].r;
}
}
printf("%d
",cnt);
return 0;
}
4.P1325 雷达安装
雷达显然都建在海岸线上更优。算出每个岛被覆盖的雷达位置区间,使每个区间里至少有一个点。
const int maxn=1005;
int x[maxn],y[maxn];
struct node{double l,r;}p[maxn];
bool cmp(node a,node b){return a.r<b.r;}
int main(){
int n=read(),d=read(),ans=1;
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
if(y[i]>d){
printf("-1
");
return 0;
}
double dt=sqrt(d*d-y[i]*y[i]);
p[i].l=x[i]-dt;p[i].r=x[i]+dt;
}
sort(p+1,p+1+n,cmp);
double tmp=p[1].r;
for(int i=2;i<=n;i++)if(p[i].l>tmp)ans++,tmp=p[i].r;
printf("%d
",ans);
return 0;
}