时间限制: 1 Sec 内存限制: 256 MB
【题目描述】
一年一度的星哥选美又拉开了帷幕
N个人报名参加选拔,每个人都有着各自的相貌参数和身材参数(不大于10000 的正整数)。你的任务是尽可能让更多人被星哥选中,而唯一要求就是,在这只队伍里面的每个人,都需满足以下不等式:
A (H− h) +B(W− w) ≤ C
其中H和W为这个人的相貌和身材, h和w为选中者中的最小相貌参数和最小身材参数,而A、 B、 C为三个不大于 10000 的正的整型常数。
现在请计算星哥最多可以选中多少人。
【输入格式】
第一行:一个整数: N(0<N<=2000)
第二行:三个分开的整数: 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
【题解】
难到我连暴力都想不出来的题目啊……然而真正有多难吗?想要枚举区间,并不是求子串而是子序列;想要dfs生成子序列,最小值不能确定很麻烦。做了一个多小时也没想到什么靠谱的方法,最后二分+dfs强行打出了一个能出样例的奇怪程序。数据范围很小,真正的数据更小,正是暴力能充分发挥作用的题目,却没有一点头绪。今天的成绩排名几乎和这道题的排名一样,可见把简单题做好的重要性。然而我现在最大的问题是:在别人眼里的简单题,在我眼里永远最难做……
既然最小值很不好确定,直接枚举最小值不就行了吗?三层循环,前两层枚举最小值,最后一层枚举所有人,在边界内且符合条件就把结果++,这样n^3的暴力对一两千的数据来说已经看得过去了。在稍微排一下序剪一下枝,轻轻松松就能打几十分。一个前缀和没想到失了几十分,一个暴力枚举,简直不能说“想到”,然而还是没做出来。图论题的暴力打得还可以,但是其他题,我的暴力约等于骗分,甚至于不是骗分简直是撞测试点。暴力和骗分最大的不同,在于暴力至少也是一种算法,就算时间空间性能都很差,至少也是需要设计的。暴力应该简单,如果实在没有办法了再优化。至于这种想不出暴力的情况,还是做的题太少而想得过于复杂。现在大家都会打暴力了,就看谁能想到正解,而且暴力不打挂了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,a,b,c,jg,ans; struct node { int h,w; }yw[1005]; int comp(const node&a,const node&b) { return (a.w==b.w)?(a.h>b.h):(a.w<b.w); } int main() { scanf("%d%d%d%d",&n,&a,&b,&c); for(int i=1;i<=n;i++) scanf("%d%d",&yw[i].h,&yw[i].w); sort(yw+1,yw+n+1,comp); jg=1; for(int j=1;j<=n;j++) { if(n-j+1<jg) break; for(int i=j;i<=n;i++) if(yw[j].h>=yw[i].h) { ans=0; for(int k=j;k<=n;k++) if((yw[k].h>=yw[i].h)&&(a*(yw[k].h-yw[i].h)+b*(yw[k].w-yw[j].w)<=c)) ans++; if(ans>jg) jg=ans; } } printf("%d",jg); return 0; }
附一个wcx大佬正解链接:http://www.cnblogs.com/hzoi-mafia/p/7295499.html
所以说还是一道数学题,不等式大力化简变形一下。能想到差分的whm很棒啊。