【题目背景】
小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光
之源的矿石交易市场,以便为飞船升级无限非概率引擎。
【问题描述】
现在有 m+1 个星球,从左到右标号为 0 到 m,小奇最初在 0 号星球。
有 n 处矿体,第 i 处矿体有 ai 单位原矿,在第 bi 个星球上。
由于飞船使用的是老式的跳跃引擎,每次它只能从第 x 号星球移动到第 x+4
号星球或 x+7 号星球。每到一个星球,小奇会采走该星球上所有的原矿,求小奇
能采到的最大原矿数量。
注意,小奇不必最终到达 m 号星球。
【输入格式】
第一行 2 个整数 n,m。
接下来 n 行,每行 2 个整数 ai,bi。
【输出格式】
输出一行一个整数,表示要求的结果。
【样例输入】
3 13
100 4
10 7
1 11
【样例输出】
101
【样例解释】
第一次从 0 到 4,第二次从 4 到 11,总共采到 101 单位原矿。
【数据范围】
对于 20%的数据 n=1,m<=10^5
对于 40%的数据 n<=15,m<=10^5
对于 60%的数据 m<=10^5
对于 100%的数据 n<=10^5,m<=10^9,1<=ai<=10^4,1<=bi<=m
距超过 17 的一定可达,那么不超过 17 的范围内暴力,超过 17 的取个最大值即可
可以把相邻的星球距离超过 17 的压缩成 18
设 x[i]为 i 号星球的原矿数,f[i]为到 i 号星球能
获得的最大原矿数,则 f[i]=max{f[i-4],f[i-7]}+x[i]
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long lol; 7 struct Node 8 { 9 lol a,b; 10 }a[100001]; 11 lol f[2000001],ans,now,s[2000001]; 12 int n,m; 13 bool cmp(Node a,Node b) 14 { 15 return a.b<b.b; 16 } 17 int main() 18 {int i,x,y; 19 freopen("mining.in","r",stdin); 20 freopen("mining.out","w",stdout); 21 cin>>n>>m; 22 for (i=1;i<=n;i++) 23 { 24 scanf("%lld%lld",&a[i].a,&a[i].b); 25 } 26 sort(a+1,a+n+1,cmp); 27 memset(f,-1,sizeof(f)); 28 now=0; 29 for (i=1;i<=n;i++) 30 if (a[i].b-a[i-1].b>=18) now+=18,s[now]+=a[i].a; 31 else now+=a[i].b-a[i-1].b,s[now]+=a[i].a; 32 f[0]=0;ans=0; 33 for (i=0;i<=now;i++) 34 if (f[i]!=-1) 35 { 36 f[i+4]=max(f[i+4],f[i]+s[i+4]); 37 f[i+7]=max(f[i+7],f[i]+s[i+7]); 38 ans=max(ans,f[i]); 39 } 40 cout<<ans; 41 }