题面:
Luogu P1156 垃圾陷阱
题目描述
卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺。
卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
假设卡门预先知道了每个垃圾扔下的时间t(0< t<=1000),以及每个垃圾堆放的高度h(1<=h<=25)和吃进该垃圾能维持生命的时间f(1<=f<=30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。
输入输出格式
输入格式:第一行为2个整数,D 和 G (1 <= G <= 100),G为被投入井的垃圾的数量。
第二到第G+1行每行包括3个整数:T (0 < T <= 1000),表示垃圾被投进井中的时间;F (1 <= F <= 30),表示该垃圾能维持卡门生命的时间;和 H (1 <= H <= 25),该垃圾能垫高的高度。
输出格式:如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。
输入输出样例
20 45 4 99 3 212 6 1013 1 1
13
说明
[样例说明]
卡门堆放她收到的第一个垃圾:height=9;
卡门吃掉她收到的第二个垃圾,使她的生命从10小时延伸到13小时;
卡门堆放第3个垃圾,height=19;
卡门堆放第4个垃圾,height=20。
第一次得分:63
问题在于这两行:
const int N = 100 + 3;int D, n, d[N][N], H, gou = 10;
数据范围啊。。。。数据上界我计算出存在 H 里面,但是在这里并没有增大数组大小。
然后就 WA 了 4 个点。
然后我就改成了这样:
const int N = 100 + 3, M = 25 + 3;int D, n, d[N][N * M], H, gou = 10;
然后就只剩下一个点 WA 了。
第二次得分:91
还是有问题????
我终于在不起眼的角落找到了(多亏了和题解代码的逐行比对,不然我一天也找不出来):
sort(r, r + n);
惊不惊喜!意不意外!!刺不刺激!!!
真刺激啊。
sort(r + 1, r + n + 1);
然后就 AC 了。
dph 一定会打我。。。
Solution code:
1 /* P1156 垃圾陷阱 2 * Au: GG 3 */ 4 5 /* Solution (orz dph): 6 7 d[i][j]: [rubbish -> n, height -> D] (value: time -> max) 8 d[0][0] = 10 9 d[i][j] = max(negative infinity,10 d[i-1][ j ] - 时间 + 生命,11 d[i-1][j-高度] - 时间)12 13 */14 15 #include16 #include 17 #include 18 #include 19 #include 20 using namespace std;21 const int N = 100 + 3, M = 25 + 3;22 int D, n, d[N][N * M], H, gou = 10;23 struct rub {24 int t, xu, h;25 bool operator < (const rub &a) const {26 return t < a.t;27 }28 } r[N];29 30 int main() {31 scanf("%d%d", &D, &n);32 for (int i = 1; i <= n; i++) {33 scanf("%d%d%d", &r[i].t, &r[i].xu, &r[i].h);34 H += r[i].h;35 }36 sort(r + 1, r + n + 1);37 memset(d, 0x80, sizeof(d));38 d[0][0] = 10;39 for (int i = 1; i <= n; i++)40 for (int j = 0; j <= H; j++) {41 if (d[i - 1][j] - r[i].t + r[i - 1].t >= 0)42 d[i][j] = max(d[i][j], d[i - 1][j] - r[i].t + r[i - 1].t + r[i].xu);43 if (j - r[i].h >= 0)44 d[i][j] = max(d[i][j], d[i - 1][j - r[i].h] - r[i].t + r[i - 1].t);45 if (d[i][j] >= 0 && j >= D) { printf("%d\n", r[i].t); return 0; }46 }47 48 for (int i = 1; i <= n; i++) {49 if (gou - r[i].t + r[i - 1].t < 0) {50 printf("%d\n", gou + r[i - 1].t); return 0;51 }52 gou += r[i].xu - r[i].t + r[i - 1].t;53 }54 printf("%d\n", r[n].t + gou);55 56 return 0;57 }