http://codeforces.com/problemset/problem/586/C
题意:1~n个孩子排成一排看病。有这么一个模型:孩子听到前面的哭声自信心就会减弱:第i个孩子看病时会发出v[i]的叫声,他后面的那个人的自信心(不是p[i+1])会减少v[i],再后面一个会减少v[i]-1,如此下去直到声音减弱为0.若某个人的自信心小于0,则他哭着跑回家,他身后的所有人会减掉d[i] 的自信。
题解:直接模拟很困难,有一个想法是将逃跑的孩子的声音和将他吓跑的(正在接诊的)声音叠加成s,省去了每次对逃跑的孩子后面所有人-d[i]的循环。
坑:
考虑如果第五个人走了,第六个人就会走到第四个人后面,这样他就会减v[4]而不是v[4]-1,所以碰到已经跑了的小孩要跳过。
我一开始还忘了减d[i]...还想递归写。。。
ac
#define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<string.h> using namespace std; typedef long long ll; const int maxn = 4000 + 5; int v[maxn], d[maxn], p[maxn]; int e[maxn]; vector<int> ans; int n; void run(int j) { for (int k = j; k <= n; k++) { if (p[k] > 0 && p[k] - d[j] < 0) { run(k); } } } int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> v[i] >> d[i] >> p[i]; } for (int i = 1; i <= n; i++) { if (p[i] >= 0) { ans.push_back(i); for (int j = i + 1; j <= n; j++) { p[j] -= v[i]; v[i]--; if (v[i] <= 0)break; } } else if (v[i]) { for (int j = i + 1; j <= n; j++) { p[j] -= d[i]; } } } cout << ans.size() << endl; for (int i = 0; i < ans.size(); i++) cout << ans[i] << ‘ ‘; cin >> n; }