Problem:
Score : 300 points

Problem Statement

There are N+1 towns. The i-th town is being attacked by A_i monsters.

We have N heroes. The i-th hero can defeat monsters attacking the i-th or (i+1)-th town, for a total of at most B_i monsters.

What is the maximum total number of monsters the heroes can cooperate to defeat?

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq A_i \leq 10^9

1 \leq B_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_{N+1}
B_1 B_2 ... B_N

Output

Print the maximum total number of monsters the heroes can defeat.

Sample Input 1

2
3 5 2
4 5

Sample Output 1

9

If the heroes choose the monsters to defeat as follows, they can defeat nine monsters in total, which is the maximum result.

The first hero defeats two monsters attacking the first town and two monsters attacking the second town.

The second hero defeats three monsters attacking the second town and two monsters attacking the third town.

Sample Input 2

3
5 6 3 8
5 100 8

Sample Output 2

22

Sample Input 3

2
100 1 1
1 100

Sample Output 3

3

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {
    InputStream is;

    int __t__ = 1;
    int __f__ = 0;
    int __FILE_DEBUG_FLAG__ = __f__;
    String __DEBUG_FILE_NAME__ = "src/B13";

    FastScanner in;
    PrintWriter out;

    ArrayList<Integer>[] g;

    public void solve() {
        int n = in.nextInt();
        int[] a = in.nextIntArray(n+1);
        int[] b = in.nextIntArray(n);
        long res = 0;
        for (int i = 0; i < n; i++) {
            int s1 = Math.min(a[i], b[i]);
            a[i] -= s1;
            b[i] -= s1;

            int s2 = Math.min(a[i+1], b[i]);
            a[i+1] -= s2;
            b[i] -= s2;
            res += s1 + s2;
        }
        System.out.println(res);
    }

    /* MOD_CALCULATION */
    static int MOD = 1_000_000_007;
    static long ADD(long a, long b) {
        return (a + b) % MOD;
    }

    static long SUB(long a, long b) {
        return (a - b + MOD) % MOD;
    }

    static long MULT(long a, long b) {
        return ((a % MOD) * (b % MOD)) % MOD;
    }

    static long POW(long a, long x) {
        long res = 1;
        for ( ; x > 0; x >>= 1) {
            if (x % 2 == 1) res = MULT(res, a);
            a = MULT(a, a);
        }

        return res;
    }

    static long DIV(long a, long b) {
        return MULT(a, POW(b, MOD - 2));
    }
    /* end */

    public void run() {
        if (__FILE_DEBUG_FLAG__ == __t__) {
            try {
                is = new FileInputStream(__DEBUG_FILE_NAME__);
            } catch (FileNotFoundException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            System.out.println("FILE_INPUT!");
        } else {
            is = System.in;
        }
        in = new FastScanner(is);
        out = new PrintWriter(System.out);

        solve();
    }

    public static void main(final String[] args) {
        new Main().run();
    }

    class FastScanner {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public FastScanner(InputStream stream) {
            this.stream = stream;
            // stream = new FileInputStream(new File("dec.in"));

        }

        int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        boolean isEndline(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; i++)
                array[i] = nextInt();

            return array;
        }

        int[][] nextIntMap(int n, int m) {
            int[][] map = new int[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextIntArray(m);
            }
            return map;
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        long[] nextLongArray(int n) {
            long[] array = new long[n];
            for (int i = 0; i < n; i++)
                array[i] = nextLong();

            return array;
        }

        long[][] nextLongMap(int n, int m) {
            long[][] map = new long[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextLongArray(m);
            }
            return map;
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        double[] nextDoubleArray(int n) {
            double[] array = new double[n];
            for (int i = 0; i < n; i++)
                array[i] = nextDouble();

            return array;
        }

        double[][] nextDoubleMap(int n, int m) {
            double[][] map = new double[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextDoubleArray(m);
            }
            return map;
        }

        String next() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        String[] nextStringArray(int n) {
            String[] array = new String[n];
            for (int i = 0; i < n; i++)
                array[i] = next();

            return array;
        }

        String nextLine() {
            int c = read();
            while (isEndline(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndline(c));
            return res.toString();
        }
    }
}

class Graph<E extends Edge> {
    private final int n;
    private final List<E>[] g;

    public Graph(int n) {
        this(n, new ArrayList[n]);
    }

    public Graph(int n, List<E>[] g) {
        this.n = n;
        this.g = g;
    }

    public void addDirectionalEdge(int u, E e) {
        g[u].add(e);
    }

    public Iterable<E> edges(int u) {
        return g[u];
    }

    public int size() {
        return n;
    }

    public long[] bellmanford(int start) {
        long[] dist = new long[n];
        Arrays.fill(dist, 1L << 62);
        dist[start] = 0;
        for (int i = 0; i < n - 1; i++) {
            for (int u = 0; u < n; u++) {
                for (Edge e : edges(u)) {
                    dist[e.to()] = Math.min(dist[e.to()], dist[u] + e.cost());
                }
            }
        }
        return dist;
    }
}

class StrongConnectedComponents<E extends Edge> {
    private final Graph<E> graph;

    public StrongConnectedComponents(Graph<E> graph) {
        this.graph = graph;
    }

    public SCCResult doit() {
        int n = graph.size();
        int[] order = new TopologicalSort<>(graph).doit();
        boolean[] visited = new boolean[n];
        int sccSize = 0;
        for (int u = n - 1; u >= 0; u--) {
            if (!visited[u]) {
                dfs(u, order, visited, ++sccSize);
            }
        }
        return new SCCResult(order, sccSize);
    }

    private void dfs(int u, int[] order, boolean[] visited, int id) {
        visited[u] = true;
        order[u] = id;
        for (Edge e : graph.edges(u)) {
            if (!visited[e.to()]) {
                dfs(e.to(), order, visited, id);
            }
        }
    }

    class SCCResult {
        final int[] order;
        final int sccSize;

        public SCCResult(int[] order, int sccSize) {
            this.order = order;
            this.sccSize = sccSize;
        }

        public <E extends Edge> Graph<E> generateNewGraph(Graph<E> graph, EdgeGenerator<E> edgeGenerator) {
            final Graph<E> newGraph = new Graph<>(sccSize);
            final UnionFindTree uft = new UnionFindTree(sccSize);
            for (int u = 0; u < graph.size(); u++) {
                for (E e : graph.edges(u)) {
                    int from = order[u];
                    int to = order[e.to()];
                    if (!uft.same(from, to)) {
                        newGraph.addDirectionalEdge(from, edgeGenerator.generate(to, e));
                    }
                }
            }
            return newGraph;
        }
    }
}

interface EdgeGenerator<E extends Edge> {
    E generate(int to, E originalEdge);
}

class TopologicalSort<E extends Edge> {
    private final Graph<E> graph;

    public TopologicalSort(Graph<E> graph) {
        this.graph = graph;
    }

    int index;
    boolean[] visited;

    public int[] doit() {
        final int n = graph.size();
        visited = new boolean[n];
        index = n - 1;

        int[] result = new int[n];
        for (int u = 0; u < n; u++) {
            if (!visited[u]) {
                dfs(u, result);
            }
        }
        if (index != -1) {
            throw new RuntimeException();
        }
        return result;
    }

    private void dfs(int u, int[] result) {
        visited[u] = true;
        for (Edge e : graph.edges(u)) {
            if (!visited[e.to()]) {
                dfs(e.to(), result);
            }
        }
        result[index--] = u;
    }
}

class EdgeImpl implements Edge {
    private final int to;
    private final long cost;

    public EdgeImpl(int to, long cost) {
        this.to = to;
        this.cost = cost;
    }

    @Override
    public int to() {
        return to;
    }

    @Override
    public long cost() {
        return cost;
    }
}

interface Edge {
    int to();
    long cost();
}

class UnionFindTree {
    int[] parent;
    int[] size;

    public UnionFindTree(int n) {
        parent = new int[n];
        size = new int[n];
        init();
    }

    public void init() {
        for (int i = 0; i < parent.length; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }

    public int find(int x) {
        if (parent[x] == x) return x;
        return parent[x] = find(parent[x]);
    }

    public boolean same(int x, int y) {
        return find(x) == find(y);
    }

    public void unite(int x, int y) {
        int xx = find(x), yy = find(y);
        if (xx == yy) return;
        parent[xx] = yy;
        size[yy] += size[xx];
    }

    public int getSize(int x) {
        return size[find(x)];
    }

    public int getSize(int x, int y) {
        int xx = find(x), yy = find(y);
        if (xx == yy)
            return size[xx];
        else
            return size[xx] + size[yy];
    }

    public String toString() {
        String res = "";
        res += Arrays.toString(parent) + "\n";
        res += Arrays.toString(size);
        return res;
    }
}