One way to efficiently solve this is to formulate it as a maximum flow problem.
Add edges between people and the tasks they can do (capacity 1).
Also add edges between a start and each person (capacity 1)
And an edge between a task and the destination (capacity = number of times that task needs to be done).
Example Python code using NetworkX:
import networkx as nx
from collections import Counter
jobs = 'IGGGFFDDCCBBB'
people = 'ABCDEFG CEI BEI CEFGI CEGI ADGI CEGI CI ADG BEI DI BCDEFI ABDF ABEFG BCEGI ACDI BD ABE BCDEFGI'
G=nx.DiGraph()
for person,tasks in enumerate(people.split()):
P = 'person'+str(person)
G.add_edge('start',P,capacity=1.0) # One person can do one thing
for task in tasks:
G.add_edge(P,'task'+task,capacity=1.0) # This person can do this task
C = Counter(jobs)
for task,count in C.items():
G.add_edge('task'+task,'end',capacity=count) # Task appears count times in our job list
print nx.max_flow(G,'start','end') >= len(jobs)