由于版权原因,没有题面。
T1
显然就是洛谷原题
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e6+5;
int a[maxn],b[maxn],n,ans,q[maxn],til,hea;
int main()
{
scanf("%d",&n);til=0;hea=1;
for (int i=1;i<=n;++i)
{
scanf("%d%d",a+i,b+i);
while (hea<=til&&a[q[hea]]>b[i]) ++hea;
ans=max(ans,i-q[hea-1]);
while (hea<=til&&a[q[til]]<=a[i]) --til;
q[++til]=i;
}
printf("%d",ans);
return 0;
}
有人写了优化暴力算法,这里造一组数据卡一下。
T2
想法很妙,但是为什么我的DP过不了?????
T3
这题可以好好讲讲。
说是贪心,但是贪心的要超时。(贪心的暴力就不赘述)
我也不知道为什么就会去考虑DP,可能是D的范围比较小,
但是由于 h 巨大无比,大多数人不会去考虑类似的想法。
显而易见,对于一个山峰,我们把它打得低于下一台炮的攻击范围后(假设高度为 H H H),一定会用下一台炮打,接下来同理,也就是说知道 H H H 后,接下来要打几步是定值,我们可以提前求好。
由于一次最多打 500 500 500 单位高度,所以 H H H 的范围肯定在 [ A i − 499 , A i ] [A_i-499,A_i] [Ai−499,Ai] 之间,而炮又只有 500 个,所以顶多是 250000 。
我们为了方便可以用 map (写 FP 的选手们,恩……早日转 C++ 吧!)
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=250005,maxm=505;
typedef long long LL;
int n,m,ans;
LL k,h[maxn];
map<LL,LL>f;
struct js{
LL a,d;
bool operator <(const js&b)const{return d>b.d||(d==b.d&&a>b.d);}
}p[maxm];
char FIL[100000],*A=FIL,*B=FIL;
#define getchar() (A==B&&(B=(A=FIL)+fread(FIL,1,100000,stdin),A==B)?EOF:*A++)
LL rad()
{
LL ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
return ret*f;
}
int main()
{
n=rad();m=rad();k=rad();
for (int i=n;i>=1;--i) h[i]=rad();
for (int i=1;i<=m;++i) p[i].a=rad(),p[i].d=rad();
sort(p+1,p+m+1);
int T=m;m=0;
for (int i=1;i<=T;++i) if (p[i].a>p[m].a) p[++m]=p[i];
f[0]=0;
LL tim,lst,L,R;
for (int i=1;i<=m;++i)
{
lst=p[i-1].a;
L=max(lst,p[i].a-p[i].d)+1;
R=p[i].a;
for (LL h=L;h<=R;++h)
tim=(h-lst-1)/p[i].d+1,f[h]=f[max((LL)0,h-tim*p[i].d)]+tim;
}
LL nee;
for (int i=1,j=1;i<=n;++i)
{
while (j<=m&&p[j].a<h[i]) ++j;
if (j<=m)
{
nee=(h[i]-p[j-1].a-1)/p[j].d+1;
h[i]-=nee*p[j].d;
if (h[i]>0) nee+=f[h[i]];
if (nee<=k) k-=nee,++ans;
else break;
}else break;
}
printf("%d %lld\n",ans,k);
return 0;
}