柠檬超市
显然是要坑精度,所以不能存实数,把性价比的分子跟分母存下来,比较大小的时候移项即可。
Code
var ans,n,s,i:longint;
w,c,a,b:qword;
begin
readln(n,s);a:=0;b:=1;ans:=0;
for i:=1 to n do
begin
readln(w,c);
if(c<=s)and(w*b>c*a)
then begin
a:=w;
b:=c;
ans:=i;
end;
end;
writeln(ans);
end.
柠檬的坦克游戏
第一反应先按照题目描述把暴力写了,写完暴力发现我理解题意了,然后进行了接近1个小时的思考(想了很多矬贪心)。我发现可以分别按D和R升序排序搞出两个序列,比某个元素优的元素是两个序列后缀(到该元素位置)交集的规模,那这个数字+1就是组数。发现这个玩意前缀和搞不了,N太大boolean集合+位运算或者boolean数组搞不了,线段树或者树状数组我想不到怎么用(据说有A掉的)。然后我看样例(样例很良心>_<)的时候突然发现如果按D降序排列,比某元素优和他是序列的前缀的一个最长下降(数据保证数字两两不同)子序列。然后无奈写了个heap加到暴力上优化,发现样例都过不了,所以意识到这这题一定是要按D排列,然后突然想起了lis,大喜,似乎按D降序排列以后按R搞最长不降子序列长度就是比他优的元素个数。然后又想了想,举了个反例发现了以上想法全部有一个大bug,如果在某元素前有多个元素R比他大然后构成一个单调上升的,那这些元素只会让长度大一,突然发现这些元素一定在一个组里,一旦下降,D也小,R也小就在下一个组里了。也就是说一个组内D减小的同时R单调上升。分到元素i时,分组的数目是原序列到i的前缀的下降序列的个数,想起Dilworth定理:最小下降序列划分=最长不降子序列(Orz wwwaaannngggrs大牛,他提高二讲过)。于是题目成功转化成LIS模型。
Code
uses math;
const maxn=100000;
var D,B,num,fz,f,g:array[1..maxn] of longint;
mid,l,r,ans,j,n,i,len:longint;
procedure swap(var a,b:longint);
var t:longint;begin t:=a;a:=b;b:=t;end;
procedure qsort(l,r:longint);
var i,j:longint;
mid:longint;
begin
i:=l;j:=r;mid:=D[(l+r)shr 1];
repeat
while(i<r)and(D[i]>mid)do inc(i);
while(j>l)and(D[j]<mid)do dec(j);
if i<=j then begin
swap(D[i],D[j]);
swap(B[i],B[j]);
swap(num[i],num[j]);
inc(i);dec(j);
end;
until i>j;
if(i<r)then qsort(i,r);
if(j>l)then qsort(l,j);
end;
begin
readln(n);len:=0;
for i:=1 to n do
begin
readln(D[i],B[i]);
num[i]:=i;
end;
qsort(1,n);
for i:=1 to n do
begin
l:=1;r:=len;ans:=0;
while l<=r do begin
mid:=l+(r-l+1)shr 1;
if G[mid]>B[i]
then begin
l:=mid+1;
ans:=mid;
end
else r:=mid-1;
end;
f[i]:=ans+1;fz[num[i]]:=f[i];
len:=max(f[i],len);
if B[i]>G[f[i]]then G[f[i]]:=B[i];
end;
for i:=1 to n do
writeln(fz[i]);
end.
柠檬当上了JC局长
不得不吐槽这个题目背景,一眼能看出来时最短路加树规,还有30min,只能放弃了。
总结
这次是最近几次模拟赛成绩最好的一次,643参赛,310有分,3个AK的,我A掉前两题,第三题没交,排名14。还是要抓紧时间,要是第三题有时间写就好了,DP还是水平不够啊。