Problem:
Problem B: Erratic Sleep Habits

Peter is a person with erratic sleep habits. He goes to sleep at twelve o'lock every midnight. He gets
up just after one hour of sleep on some days; he may even sleep for twenty-three hours on other days.
His sleeping duration changes in a cycle, where he always sleeps for only one hour on the first day of the
cycle.

Unfortunately, he has some job interviews this month. No doubt he wants to be in time for them. He can
take anhydrous caffeine to reset his sleeping cycle to the beginning of the cycle anytime. Then he will
wake up after one hour of sleep when he takes caffeine. But of course he wants to avoid taking caffeine
as possible, since it may affect his health and accordingly his very important job interviews.

Your task is to write a program that reports the minimum amount of caffeine required for Peter to attend
all his interviews without being late, where the information about the cycle and the schedule of his
interviews are given. The time for move to the place of each interview should be considered negligible.

Input

The input consists of multiple datasets. Each dataset is given in the following format:

T

t1 t2 ... tT

N

D1 M1

D2 M2

...

DN MN

T is the length of the cycle (1 ≤ T ≤ 30); ti (for 1 ≤ i ≤ T ) is the amount of sleep on the i-th day of the
cycle, given in hours (1 ≤ ti ≤ 23); N is the number of interviews (1 ≤ N ≤ 100); Dj (for 1 ≤ j ≤ N)
is the day of the j-th interview (1 ≤ Dj ≤ 100); Mj (for 1 ≤ j ≤ N) is the hour when the j-th interview starts (1 ≤ Mj ≤ 23).

The numbers in the input are all integers. t1 is always 1 as stated above. The day indicated by 1 is the
first day in the cycle of Peter's sleep.

The last dataset is followed by a line containing one zero. This line is not a part of any dataset and should not be processed.

Output

For each dataset, print the minimum number of times Peter needs to take anhydrous caffeine.

Sample Input

2
1 23
3
1 1
2 1
3 1
0

Output for the Sample Input

2

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
import static java.lang.System.*;
import static java.lang.Math.*;

public class Main {

	Scanner sc = new Scanner(in); 
	
	void run() {
		int[] t = new int[30];
		int[] time = new int[101];
		int[] c = new int[101];
		int[][] cost = new int[101][101];
		int[] dis = new int[101];
		boolean[] used = new boolean[101];
		int INF = Integer.MAX_VALUE/2;
		while (true) {
			int T = sc.nextInt();
			if (T == 0) break;
			for (int i = 0; i < T; i++)
				t[i] = sc.nextInt();
			int N = sc.nextInt();
			Arrays.fill(time, INF);
			int max = -1;
			for (int i = 0; i < N; i++) {
				int d = sc.nextInt(), m = sc.nextInt();
				time[d] = min(time[d],m);
				max = max(max, d);
			}
			
			I:for (int i = 1; i <= max; i++) {
				for (int j = i; j < i+T && j <= max; j++) {
					if (time[j] < t[j-i]) {
						c[i] = j-1;
						continue I;
					}
				}
				c[i] = (max <= i+T-1) ? max : i+T-1;
			}
			
			
			for (int i = 0; i < 101; i++)
				Arrays.fill(cost[i], INF);
			
			for (int i = 1; i < max; i++) {
				for (int j = i+1; j <= c[i]; j++) {
					cost[i][j] = 1;
				}
				if (c[i] != max) {
					if (c[i]-i == T-1) {
						cost[i][c[i]+1] = 0;
					} else {
						cost[i][c[i]+1] = 1;
					}
				}
			}
			
			Arrays.fill(dis, INF);
			Arrays.fill(used, false);
			dis[1] = 0;
			while (true) {
				int v = -1;
				for (int i = 1; i <= max; i++) {
					if (!used[i] && (v == -1 || dis[i] < dis[v])) v = i;
				}
				if (v == -1) break;
				used[v] = true;
				for (int i = 1; i <= max; i++) {
					dis[i] = min(dis[i], dis[v]+cost[v][i]);
				}
			}
			int res = INF;
			for (int i = 1; i <= max; i++) {
				if (c[i] == max)
					res = min(res, dis[i]);
			}
			out.println(res);
		}
	}
	
	public static void main(String[] args) {
		new Main().run();
	}

}