Vasya and Endless Credits (Codeforces 1107F)
Tags: DP, graph matchings

Vasya wants to buy himself a nice new car. Unfortunately, he lacks some money. Currently he has exactly 0 burles.However, the local bank has $$$n$$$ credit offers. Each offer can be described with three numbers $$$a_i$$$, $$$b_i$$$ and $$$k_i$$$. Offers are numbered from $$$1$$$ to $$$n$$$. If Vasya takes the $$$i$$$-th offer, then the bank gives him $$$a_i$$$ burles at the beginning of the month and then Vasya pays bank $$$b_i$$$ burles at the end of each month for the next $$$k_i$$$ months (including the month he activated the offer). Vasya can take the offers any order he wants.Each month Vasya can take no more than one credit offer. Also each credit offer can not be used more than once. Several credits can be active at the same time. It implies that Vasya pays bank the sum of $$$b_i$$$ over all the $$$i$$$ of active credits at the end of each month.Vasya wants to buy a car in the middle of some month. He just takes all the money he currently has and buys the car of that exact price.Vasya don't really care what he'll have to pay the bank back after he buys a car. He just goes out of the country on his car so that the bank can't find him anymore.What is the maximum price that car can have?

Input: The first line contains one integer $$$n$$$ ($$$1 \le n \le 500$$$) — the number of credit offers.Each of the next $$$n$$$ lines contains three integers $$$a_i$$$, $$$b_i$$$ and $$$k_i$$$ ($$$1 \le a_i, b_i, k_i \le 10^9$$$).

Output: Print one integer — the maximum price of the car.

Note: In the first example, the following sequence of offers taken is optimal: 4 $$$\rightarrow$$$ 3.The amount of burles Vasya has changes the following way: 5 $$$\rightarrow$$$ 32 $$$\rightarrow$$$ -86 $$$\rightarrow$$$ .... He takes the money he has in the middle of the second month (32 burles) and buys the car.The negative amount of money means that Vasya has to pay the bank that amount of burles.In the second example, the following sequence of offers taken is optimal: 3 $$$\rightarrow$$$ 1 $$$\rightarrow$$$ 2.The amount of burles Vasya has changes the following way: 0 $$$\rightarrow$$$ 300 $$$\rightarrow$$$ 338 $$$\rightarrow$$$ 1337 $$$\rightarrow$$$ 236 $$$\rightarrow$$$ -866 $$$\rightarrow$$$ .... 

Sample Inputs:
4
10 9 2
20 33 1
30 115 1
5 3 2

3
40 1 2
1000 1100 5
300 2 1

Sample Outputs:
32

1337

Solution (Python):
n = int(input())
if n == 0:
    print('0')
else:
    data = []
    ans = 0
    for i in range(n):
        line = list(map(lambda entry: int(entry), input().split()))
        x = line[0] - line[1] * line[2]
        if x > 0:
            ans += x
            line[0] -= x
        data.append((line[0], line[1]))
    data.sort(key=lambda entry: -entry[1])
    dp = [[0 for i in range(n)]]
    for j in range(n):
        x = data[j][0]
        nextline = [max(x, dp[-1][0])]
        for i in range(1, n):
            x -= data[j][1]
            nextline.append(max(x + dp[-1][i - 1], nextline[-1], dp[-1][i]))
        dp.append(nextline)
    ans += dp[n][n - 1]
    print(ans)

Solution (Python):
n = int(input())
a = [tuple(map(int, input().split())) for i in range(n)]
a = [(y, x, k) for (x, y, k) in a]
a.sort(reverse=True)
dp = [[-1] * (n + 1) for i in range(n)]

def f(i, j):
    if i < 0 or j < -1:
        return 0
    if dp[i][j] == -1:
        (y, x, k) = a[i]
        dp[i][j] = f(i - 1, j) + max(0, x - k * y)
        if 0 <= j < k:
            dp[i][j] = max(dp[i][j], x - j * y + f(i - 1, j - 1))
    return dp[i][j]
print(max((f(n - 1, j) for j in range(-1, n))))

Solution (Python):
from sys import stdin
n = int(input())
t = stdin.read().splitlines()
a = [list(map(int, i.split())) for i in t]
a.sort(reverse=True, key=lambda k: (k[1], k[0], k[2]))
dp = [[0] * (n + 1) for _ in range(n + 1)]
for i in range(n):
    for l in range(n + 1):
        dp[i + 1][l] = max(dp[i + 1][l], dp[i][l], dp[i][l] + a[i][0] - a[i][1] * a[i][2])
        if l < n:
            dp[i + 1][l + 1] = max(dp[i + 1][l + 1], dp[i][l] + a[i][0] - a[i][1] * l)
print(max(dp[n]))