You are correct. By assigning declaring that the initialized object should be stored in the list "list" which only holds "Person" objects, when you use list[i] you will only be able to use methods that objects of the type "Person" can use.
To give you an example from reality:
You visit a car vendor and ask him if a specific car has an air conditioning system. The vendor says yes and you enter the car. You then try to activate the ac system by trying to follow a guide which explains how to turn it on for all cars. Of course, since not all cars have an ac system, your guide book is empty and you can't follow any steps.
Java/Object oriented programming has a wonderful solution for this problem. The solution is called "overwrite methods".
I would do the following if I were you:
1) Add a "getSal()" method to the "Employee" class, which simply returns 0.
2) in every class that extends "Employee" overwrite the "getSal()" method by using the @Overwrite annotation before any new "getSal()" method. Let the getSal() method do what "getYrSalery()" and "getHourlySalery()" did before + move the "Full"/"Half" evaluation into the "getSal()" method that replaces "getHourlySal()" in the Staff class.
3) Change your last for-loop. Only check if (list[i] insanceof Employee"), delete all other checks. Inside the if block you want to add a try-catch structure, that catche any exceptions of the object-type Exception. Inside the try block you want to write:
Employee e = list[i];
pay = pay + e.getSal();
What this does is the following: if list[i] is either an Employee, or an instance of a class that somehow extends Employee, you will work with an Employee object. This object can call e.getSal(), which should be implemented in all your relevant classes.
What I've written above should work for now, however using an interface would make things easier in the future. You might want to revisit this exercise once you know how to use "Interface" objects.