首页 > 代码库 > [Codeup 25482] Beauty

[Codeup 25482] Beauty

25482: Beauty

时间限制: 1 Sec  内存限制: 128 MB
献花: 7  解决: 3
[献花][花圈][TK题库]

题目描述

一年一度的星哥选美又拉开了帷幕

N个人报名参加选拔,每个人都有着各自的相貌参数和身材参数(不大于10000的正整数)。你的任务是尽可能让更多人被星哥选中,而唯一要求就是,在这只队伍里面的每个人,都需满足以下不等式:

 A (H−h)+B(W−w)≤C

其中H和W为这个人的相貌和身材,h和w为选中者中的最小相貌参数和最小身材参数,而A、B、C为三个不大于10000的正的整型常数。

现在请计算星哥最多可以选中多少人。

输入

第一行:一个整数:N

第二行:三个分开的整数:A,B和C

第三行到第N+2行:每行有两个用空格分开的整数,分别表示一个人的相貌参数和身材参数

输出

第一行:最多被选的人数

样例输入

8 1 2 4 5 1 3 2 2 3 2 1 7 2 6 4 5 1 4 3

样例输出

5

提示

第1,2,3,4,7号可以组成一支符合要求的队伍,没有更大的队伍了

这道题第一眼看成离散化然而发现数据范围不大并不需要离散化OwO

对于这题似乎有两种解法, 一种是 $O(n^2log(n))$ 的, 还有一种似乎是 $O(n*w_{max})$ 的. 根据某dalao $wq$ 所言还能用 $CDQ$ 分治水过去w.

这里只讲第二种好了w实际评测中发现时间消耗比第一种少 $30\%$ 左右

首先枚举 $h$, 然后在内层枚举要处理的结点, 这样我们可以得到 $h$ $H$ $W$ 三个值. 结合 $A$ $B$ $C$ 与不等式我们可以计算出要使该要处理的结点被选中所需的最小 $w$ 值. 然后再根据 $W$ 值可以计算出要使该结点要被选中, $w$ 所应当落在的区间. 然后我们在数组中对区间进行差分, 计算完对于某个 $h$ 的所有结点的 $w$ 区间后对差分所得数组求前缀和处理出对于每个 $w$ 值有多少个结点被选中. 然后根据结点信息枚举可能的 $w$ 并对最终结果取 $max$. 对于所有 $n$ 个 $h$ 都计算一下, 然后全局最大值即为最优解.

其中要注意的是: 由于我们所枚举的 $h$ 是最小值, 所以对于 $H$ 值小于我们所枚举的 $h$ 的结点应直接跳过防止影响答案. 而由于 $w$ 是最小值, 则 $B(W-w) \geq 0$ , 所以 $A(H-h) \leq C$ , 所以对于 $A(H-h) > C$ 的情况我们也要直接跳过防止影响答案.

参考代码如下:

GitHub

技术分享
  1 #include <queue>  2 #include <cstdio>  3 #include <cstring>  4 #include <cstdlib>  5 #include <iostream>  6 #include <algorithm>  7   8 const int MAXN=1510;  9  10 struct Point{ 11     int x; 12     int y; 13     Point(int x=0,int y=0){ 14         this->x=x; 15         this->y=y; 16     } 17 }; 18  19 int n; 20 int m; 21 int l=0,r=0; 22 int xa,ya,xb,yb; 23 Point q[30000100]; 24 int dis[MAXN][MAXN]; 25 int melt[MAXN][MAXN]; 26 bool visited[MAXN][MAXN]; 27  28 void BFS(); 29 void gch(char&); 30 void Initialize(); 31 void SPFA(int,int); 32  33 int main(){ 34     Initialize(); 35     BFS(); 36     SPFA(xa,ya); 37     printf("%d\n",dis[xb][yb]); 38     return 0; 39 } 40  41 void SPFA(int x,int y){ 42     memset(visited,0,sizeof(visited)); 43     dis[x][y]=0; 44     q[r++]=(Point(x,y)); 45     visited[x][y]=true; 46     while(l<r){ 47         x=q[l].x; 48         y=q[l].y; 49         l++; 50         visited[x][y]=false; 51         if(x>1&&dis[x][y]<dis[x-1][y]&&dis[x-1][y]!=melt[x-1][y]){ 52             dis[x-1][y]=std::max(dis[x][y],melt[x-1][y]); 53             if(!visited[x-1][y]){ 54                 visited[x-1][y]=true; 55                 q[r++]=(Point(x-1,y)); 56             } 57         } 58         if(x<n&&dis[x][y]<dis[x+1][y]&&dis[x+1][y]!=melt[x+1][y]){ 59             dis[x+1][y]=std::max(dis[x][y],melt[x+1][y]); 60             if(!visited[x+1][y]){ 61                 visited[x+1][y]=true; 62                 q[r++]=(Point(x+1,y)); 63             } 64         } 65         if(y>1&&dis[x][y]<dis[x][y-1]&&dis[x][y-1]!=melt[x][y-1]){ 66             dis[x][y-1]=std::max(dis[x][y],melt[x][y-1]); 67             if(!visited[x][y-1]){ 68                 visited[x][y-1]=true; 69                 q[r++]=(Point(x,y-1)); 70             } 71         } 72         if(y<m&&dis[x][y]<dis[x][y+1]&&dis[x][y+1]!=melt[x][y+1]){ 73             dis[x][y+1]=std::max(dis[x][y],melt[x][y+1]); 74             if(!visited[x][y+1]){ 75                 visited[x][y+1]=true; 76                 q[r++]=(Point(x,y+1)); 77             } 78         } 79     } 80 } 81  82 void BFS(){ 83     memset(visited,0,sizeof(visited)); 84     while(l<r){ 85         int x=q[l].x; 86         int y=q[l].y; 87         ++l; 88         if(x>1&&!visited[x-1][y]&&melt[x][y]+1<melt[x-1][y]){ 89             melt[x-1][y]=melt[x][y]+1; 90             visited[x-1][y]=true; 91             q[r++]=(Point(x-1,y)); 92         } 93         if(x<n&&!visited[x+1][y]&&melt[x][y]+1<melt[x+1][y]){ 94             melt[x+1][y]=melt[x][y]+1; 95             visited[x+1][y]=true; 96             q[r++]=(Point(x+1,y)); 97         } 98         if(y>1&&!visited[x][y-1]&&melt[x][y]+1<melt[x][y-1]){ 99             melt[x][y-1]=melt[x][y]+1;100             visited[x][y-1]=true;101             q[r++]=(Point(x,y-1));102         }103         if(y<m&&!visited[x][y+1]&&melt[x][y]+1<melt[x][y+1]){104             melt[x][y+1]=melt[x][y]+1;105             visited[x][y+1]=true;106             q[r++]=(Point(x,y+1));107         }108     }109 }110 111 void Initialize(){112     char ch;113     memset(dis,0x3F,sizeof(dis));114     memset(melt,0x3F,sizeof(melt));115     scanf("%d%d",&n,&m);116     for(int i=1;i<=n;i++){117         for(int j=1;j<=m;j++){118             gch(ch);119             if(ch==.){120                 q[r++]=(Point(i,j));121                 melt[i][j]=0;122                 visited[i][j]=true;123             }124             else if(ch==L){125                 q[r++]=(Point(i,j));126                 melt[i][j]=0;127                 visited[i][j]=true;128                 if(xa==0){129                     xa=i;130                     ya=j;131                 }132                 else{133                     xb=i;134                     yb=j;135                 }136             }137         }138     }139 }140 141 void gch(char& target){142     do{143         target=getchar();144     }while(target!=.&&target!=X&&target!=L);145 }
Backup

以及日常图包w

技术分享

 

[Codeup 25482] Beauty