Problem:
Score : 100 points

Problem Statement

There are N blocks, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N), Block i has a weight of w_i, a solidness of s_i and a value of v_i.

Taro has decided to build a tower by choosing some of the N blocks and stacking them vertically in some order.
Here, the tower must satisfy the following condition:

For each Block i contained in the tower, the sum of the weights of the blocks stacked above it is not greater than s_i.

Find the maximum possible sum of the values of the blocks contained in the tower.

Constraints

All values in input are integers.

1 \leq N \leq 10^3

1 \leq w_i, s_i \leq 10^4

1 \leq v_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
w_1 s_1 v_1
w_2 s_2 v_2
:
w_N s_N v_N

Output

Print the maximum possible sum of the values of the blocks contained in the tower.

Sample Input 1

3
2 2 20
2 1 30
3 1 40

Sample Output 1

50

If Blocks 2, 1 are stacked in this order from top to bottom, this tower will satisfy the condition, with the total value of 30 + 20 = 50.

Sample Input 2

4
1 2 10
3 1 10
2 4 10
1 6 10

Sample Output 2

40

Blocks 1, 2, 3, 4 should be stacked in this order from top to bottom.

Sample Input 3

5
1 10000 1000000000
1 10000 1000000000
1 10000 1000000000
1 10000 1000000000
1 10000 1000000000

Sample Output 3

5000000000

The answer may not fit into a 32-bit integer type.

Sample Input 4

8
9 5 7
6 2 7
5 7 3
7 8 8
1 9 6
3 3 3
4 1 7
4 5 5

Sample Output 4

22

We should, for example, stack Blocks 5, 6, 8, 4 in this order from top to bottom.

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

import java.util.*;
import java.io.*;
class Main {
    static class Triplet implements Comparable<Triplet> {
        int weight;
        int strength;
        long value;
        Triplet(int weight, int strength, long value) {
            this.weight = weight;
            this.strength = strength;
            this.value = value;
        }
        public int compareTo(Triplet other) {
            return this.weight+this.strength-other.weight-other.strength;
        }
    }
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] weights = new int[n];
        int[] strengths = new int[n];
        long[] values = new long[n];
        Triplet[] triplets = new Triplet[n];
        int maxWeight = 0;
        for(int i = 0; i<n; i++) {
            weights[i] = sc.nextInt();
            strengths[i] = sc.nextInt();
            values[i] = sc.nextLong();
            triplets[i] = new Triplet(weights[i], strengths[i], values[i]);
            maxWeight = Math.max(maxWeight, weights[i]);
        }
        Arrays.sort(triplets);
        long[] dp = new long[n*maxWeight+1];
        for(int i = 0; i<n; i++) {
            for(int j = triplets[i].strength; j>=0; j--) {
                int newWeight = j+triplets[i].weight;
                if(newWeight<dp.length)
                    dp[newWeight] = Math.max(dp[newWeight], dp[j]+triplets[i].value);
            }
        }
        long max = 0;
        for(long i: dp)
            max = Math.max(max, i);
        System.out.println(max);
    }
}