Here's a sketch of how you could approach it using the reshape2 package and base functions.
#sample data
set.seed(734)
dd<-data.frame(
    Name=letters[1:20],
    HW1=rpois(20,7),
    HW2=rpois(20,7),
    HW3=rpois(20,7),
    Quiz1=rpois(20,15),
    Quiz2=rpois(20,15),
    Quiz3=rpois(20,15)
)
Now I convert it to long format and split apart the field names
require(reshape2)
mm<-melt(dd, "Name")
mm<-cbind(mm,
    colsplit(gsub("(\\w+)(\\d+)","\\1:\\2",mm$variable, perl=T), ":",
    names=c("type","number"))
)
Now i can use by() to get a data.frame for each name and do the rest of the calculations. Here i just drop the lowest homework and lowest quiz and i give homework a weight of .2 and quizzes a weight of .8 (assuming all home works were worth 15pts and quizzes 25 pts).
grades<-unclass(by(mm, mm$Name, function(x) {
    hw <- tail(sort(x$value[x$type=="HW"]), -1);
    quiz <- tail(sort(x$value[x$type=="Quiz"]), -1);
    (sum(hw)*.2 + sum(quiz)*.8) / (length(hw)*15*.2+length(quiz)*25*.8)
}))
attr(grades, "call")<-NULL   #get rid of crud from by()
grades;
Let's check our work. Look at student "c"
   Name HW1 HW2 HW3 Quiz1 Quiz2 Quiz3
      c   6   9   7    21    20    14
Their grade should be 
((9+7)*.2+(21+20)*.8) / ((15+15)*.2 + (25+25)*.8) = 0.7826087
and in fact, we see
grades["c"] == 0.7826087