#include #include #include using namespace std; const int MAX_D = 5000; const int INF = INT_MAX; // should be big enough... bool visit[MAX_D]; int clean[MAX_D], mess[MAX_D]; int D, F; int memo[MAX_D+1][MAX_D+1]; // max mess I can have to start day d, if I can still clean k times, and // still satisfy the constraints int f(int d, int k) { if (k < 0) { return -1; } // no more days to worry about if (d >= D) { return INF; } int &ans = memo[d][k]; if (ans >= -1) { return ans; } ans = -1; // if today is visit day, we must have no mess if (visit[d]) { // if we don't clean today then we must have no mess today, and we have to // be able to continue if (f(d+1, k) >= 0 && mess[d] == 0) { ans = max(ans, 0); } // or we clean today if (f(d+1, k-1) >= 0) { // this could be negative...then there is no way to do it ans = max(ans, clean[d] - mess[d]); } } else { // don't clean today int temp = f(d+1, k); if (temp >= 0) { ans = max(ans, temp - mess[d]); } // or clean temp = f(d+1, k-1); if (temp >= 0) { ans = max(ans, temp + clean[d] - mess[d]); } } return ans; } int main() { cin >> D >> F; for (int i = 0; i < D; i++) { cin >> mess[i] >> clean[i]; } for (int i = 0; i < F; i++) { int d; cin >> d; visit[d-1] = true; } for (int d = 0; d <= D; d++) { fill(memo[d], memo[d]+D+1, -2); } for (int k = 0; k <= D; k++) { if (f(0, k) >= 0) { cout << k << endl; return 0; } } cout << -1 << endl; return 0; }