Jumping Machine
Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 512 megabytes
Young inventor has created a new jumping machine. In order to test it, he brought it to the testing
polygon. The polygon is an infinite square grid.
Initially, the machine is located in the cell (0, 0). The machine has n springs, the i-th spring has the force
of li and allows the machine to jump li cells up or li cells to the right. Therefore this spring allows the
machine to get from cell (x, y) either to cell (x + li
, y), or to cell (x, y + li). After jumping, the spring is
thrown back and cannot be reused. The machine can use the springs in any order.
During the tests the cells, that the machine will fly over, will be stained with machine oil. In order not
to clean the grid after himself, the inventor has decided to put a protective mat on each cell the machine
could potentially fly over.
Now the inventor is wondering how many protective mats he needs to bring to the test with him.
Input
The first line of input contains n — the number of springs that the machine has (1 ≤ n ≤ 100). The
second line contains n integers li — the springs forces (li ≥ 1; 1 ≤ l1 + l2 + · · · + ln ≤ 106
).
Output
Output a single integer: the number of mats that inventor needs to bring.
Example
standard input
2
4 2
standard output
22
Explanation
All the cells that can get dirty when the machine jumps in the example test are colored orange one the
figure below
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
unordered_map<int, int> ma;
int n, l[N], dp[N], sum1[N];
vector<int> s;
int main() {
ios::sync_with_stdio(false);
cin >> n;
LL sum = 0, i, j;
for (i = 1; i <= n; i++) {
cin >> l[i];
sum += l[i];
}
dp[0] = 1;
for (i = 1; i <= n; i++) {
for (j = sum; j >= l[i]; j--) {
if (dp[j - l[i]] && dp[j] == 0) {
dp[j] = 1;
s.push_back(j);
}
}
}
sort(s.begin(), s.end());
int len = s.size();
for (i = 0; i < len; i++) {
ma[s[i]] = i + 1;
}
LL ans = 2 * sum + 1;
for (i = 1; i < sum; i++) {
if (dp[i]) {
ans += sum - i;
}
}
for (i = 1; i < sum; i++) { //两个for循环可以合并,但我感觉这样写好理解
if (dp[i]) {
ans += i - ma[i];
}
}
cout << ans << '\n';
}