题意:
N<=4000小孩排队治牙,每个小孩有(vi,di,pi)属性三元组
然后每个小孩治牙就会发出噪音,使得他后面vi个人自信值pi减少vi→1
如果pi某一时刻为负了,这个小孩就会哭跑了,然后他后面每个的pi减少di
问最后留下多少小孩治好了牙, 顺序输出
分析:
坑!如果累加extra会爆int,然后小孩跑了就不要给他减少前面的dec了
代码:
//
// Created by TaoSama on 2015-10-12
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n;
long long v[N], d[N], p[N];
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(scanf("%d", &n) == 1) {
for(int i = 1; i <= n; ++i) scanf("%I64d%I64d%I64d", v + i, d + i, p + i);
vector<int> ans;
for(int i = 1; i <= n; ++i) {
if(p[i] >= 0) {
ans.push_back(i);
long long j, dec = v[i], extra = 0;
for(j = i + 1; dec && j <= n; ++j) {
if(p[j] >= 0) {
p[j] -= dec + extra;
if(p[j] < 0) extra += d[j];
--dec;
}
}
for(; extra && j <= n; ++j) {
if(p[j] >= 0) {
p[j] -= extra;
if(p[j] < 0) extra += d[j];
}
}
}
}
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); ++i)
printf("%d ", ans[i]);
puts("");
}
return 0;
}