P7777 『JROI-2』Shelter
这里提供一个 的二分做法。
为了使代价最小,对于第一种抓取方式,我们尽量取较小的数;对于第二种抓取方式,我们尽量取相邻的数。
于是,我们要找到一个数 ,使 的数用第一种抓法, 用第二种抓法,且代价最小。这具有单调性,于是考虑二分。
首先是边界, 自然是 ,但因为第二种抓法的个数是偶数,所以要保证 和 奇偶性相同,因此 必须为 。
接下来就考虑一个 是属于哪一种了。
-
如果 和 奇偶性相同,那么与 相邻的数就为 。
-
如果 和 奇偶性不同,那么与 相邻的数就为 。
以上规律可以通过打表发现,总结一下就有了通项判定式 。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t;
ll n,p,q,ans,l,r,mid;
ll read()
{
ll x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
void write(ll X){
if(X<0) {putchar('-'); X=~(X-1);}
int s[21],top=0;
while(X) {s[++top]=X%10; X/=10;}
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
}
int main()
{
t=read();
while(t--)
{
n=read();
p=read();
q=read();
l=n&1,r=n;
while(l<r)
{
mid=(l+r+1)>>1;
if((mid*2-1+2*((n&1)-(mid&1)!=0))*p<q)
l=mid;
else
r=mid-1;
}
write(l*(l+1)/2*p+(n-l)/2*q);
putchar('\n');
}
return 0;
}
当然,细心 ctj 的你一定会发现,这个代码其实并不能通过本题,原因是本题原来时限为 2s,无优化可以轻松过。
但出题人为了只让 的算法过,把时限改成了 500ms,不过这个算法加上快读也能过。
但出题人仍不死心,把时限调成了 300ms,不过道高一尺,魔高一丈,不过再加上快写等优化仍等稳过,开 O2 后吊打出题人。

相关帖子。

浙公网安备 33010602011771号