#include <bits/stdc++.h>
using namespace std;

#define DUMP(x) cerr << #x << "=" << x << endl
#define DUMP2(x, y) cerr<<"("<<#x<<", "<<#y<<") = ("<<x<<", "<<y<<")"<< endl
#define BINARY(x) static_cast<bitset<16> >(x)

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for (int i=m;i<(int)(n);i++)

#define in_range(x, y, w, h) (0<=(int)(x) && (int)(x)<(int)(w) && 0<=(int)(y) && (int)(y)<(int)(h))
#define ALL(a) (a).begin(),(a).end()

typedef long long ll;
const int INF   = 1e9;
const ll  INFLL = 1e18;
typedef pair<int, int> PII;
int dx[4]={0, -1, 1, 0}, dy[4]={-1, 0, 0, 1};

const int MAX_V = 2000;

class MinCostFlow {
    struct edge { int to, cap, rev, cost;};
    vector<edge> G[MAX_V];

    int V;
    
    int dist[MAX_V];
    int prevv[MAX_V], preve[MAX_V];
    
public:
    MinCostFlow() {V=MAX_V;}
    MinCostFlow(int v) {
        V = v;
    }
    
    void add_edge(int from, int to, int cap, int cost) {
        G[from].push_back((edge){to, cap, (int)G[to].size(), cost});
        G[to].push_back((edge){from, 0, (int)G[from].size()-1, -cost});
    }
    
    // ????°??????¨???
    int min_cost_flow(int s, int t, int f) {
        int res=0;
        while (f>0) {
            fill(dist, dist+V, INF);
            dist[s]=0;
            bool update=true;
            while (update) {
                update = false;
                for (int v=0; v<V; v++) {
                    if (dist[v]==INF) continue;
                    for (int i=0; i<G[v].size(); i++) {
                        edge &e = G[v][i];
                        if (e.cap>0 && dist[e.to] > dist[v] + e.cost) {
                            dist[e.to] = dist[v] + e.cost;
                            prevv[e.to] = v;
                            preve[e.to] = i;
                            update = true;
                        }
                    }
                }
            }
            
            if (dist[t] == INF) {
                return -1;
            }
            
            int d=f;
            for (int v=t; v!=s; v=prevv[v]) {
                d = min(d, G[prevv[v]][preve[v]].cap);
            }
            f -= d;
            res += d*dist[t];
            for (int v=t; v!=s; v=prevv[v]) {
                edge &e = G[prevv[v]][preve[v]];
                e.cap -= d;
                G[v][e.rev].cap += d;
            }
        }
        return res;
    }
};

int main()
{
    ios::sync_with_stdio(false);

    int N, M, K;
    cin >> N >> M >> K;

    M++;

    vector<vector<int>> A(M, vector<int>(N));
    vector<int> T(M-1);

    rep(i, M) {
        rep(j, N) {
            cin >> A[i][j];
        }
    }

    rep(i, M-1) cin >> T[i];
 
    // Node 0            : ?????????
    // Node 1 - N        : ??¬?????????
    // Node N+1 - N+M    : ??????+??????
    // Node N+M+1        : ?§?????????°?????¶???
    // Node N+M+2        : ?????????

    const int SOURCE = 0;
    const int SINK   = N+M+2;
    const int X      = N+M+1;

    MinCostFlow flow(N+M+10);

    rep(i, N) {
        flow.add_edge(SOURCE, 1+i, 1, 0);
    }

    rep(i, N) {
        rep(j, M) {
            flow.add_edge(1+i, N+1+j, 1, 100 - A[j][i]);
        }
    }

    flow.add_edge(N+1, SINK, INF, 0);

    if (M > 1) {
        rep(i, M-1) {
            flow.add_edge(N+2+i, X, T[i], 0);
        }

        flow.add_edge(X, SINK, N-K, 0);
    }

    cout << N*100 - flow.min_cost_flow(0, SINK, N) << endl;
}