问题描述
【题目背景】
小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎。
【问题描述】
现在有m+1个星球,从左到右标号为0到m,小奇最初在0号星球。
有n处矿体,第i处矿体有ai单位原矿,在第bi个星球上。
由于飞船使用的是老式的跳跃引擎,每次它只能从第x号星球移动到第x+4号星球或x+7号星球。每到一个星球,小奇会采走该星球上所有的原矿,求小奇能采到的最大原矿数量。
注意,小奇不必最终到达m号星球。
输入格式
第一行2个整数n,m。
接下来n行,每行2个整数ai,bi。
输出格式
输出一行一个整数,表示要求的结果。
样例输入 1
3 13
100 4
10 7
1 11
样例输出 1
101
样例输入 2
15 200
9896 156
6614 57
7 174
8529 5
6464 74
1171 74
9749 70
225 168
1175 115
8224 192
2968 92
9769 45
7025 150
9981 112
9337 172
样例输出 2
67784
提示
【样例解释】
第一次从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
【题目分析】
(作者懒,有缘再补)
【标程参考】
1 #include<iostream> 2 #include<algorithm> 3 #define RG register 4 #define R RG int 5 #define inf -999999999 6 #define maxn 1000005 7 using namespace std; 8 int n, m, A; 9 int f[maxn], ff[maxn]; 10 bool anterior[20] = {1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1}; // 打表 11 struct node { 12 int a, b; 13 };node Planet[maxn]; 14 bool cmp(node a, node b) { 15 return a.b < b.b; 16 } 17 inline int read() { 18 int s = 0; 19 char c = getchar(); 20 while (c < '0' || c > '9')c = getchar(); 21 while (c >= '0' && c <= '9') 22 s = s * 10 + c - '0', c = getchar(); 23 return s; 24 } 25 void ini() { 26 n = read(); 27 m = read(); 28 for (R i = 1; i <= n; ++ i) { 29 Planet[i].a = read(); 30 Planet[i].b = read(); 31 } 32 sort(Planet + 1, Planet + n + 2, cmp); 33 } 34 void solve() { 35 for(R i = 2; i <= n + 1; ++ i) { 36 f[i] = inf; 37 int j = i - 1; 38 while (j > 0 && (Planet[i].b - Planet[j].b <= 18)) { 39 if (anterior[Planet[i].b - Planet[j].b]) 40 f[i] = max(f[i], f[j] + Planet[i].a); 41 -- j; 42 } 43 if (Planet[i].b - Planet[j].b > 18) 44 f[i] = max(f[i], ff[j] + Planet[i].a); 45 ff[i] = max(ff[i - 1], f[i]); 46 A = max(A, f[i]); 47 } 48 printf("%d", A); 49 } 50 int main() { 51 ini(); 52 solve(); 53 return 0; 54 }
【传送门】http://oi.nks.edu.cn/zh/Problem/Details/4270