Codeforces 789E

To K concentrations were $ frac {a_i} {1000} $ drink, requires each beverage integer L, against the concentration of $ frac {N} {1000} $ beverage. Seeking at least take a few liters of beverages.

data range

$ 0leq nleq 1000,1leq kleq 10 ^ 6 $

$0leq ai leq 1000,a_i in Z$

practice

By the pigeonhole principle, different concentrations of up to 1001 kinds of drinks.
Let K is the number of different concentrations. Each beverage provided by the xi liters, there
$$
FRAC sum_ {{I = FRAC. 1} ^ {a_i Kx_itimes} {1000} {} {I = sum_ Kx_i. 1} ^ {N} = FRAC} {1000}
$ $
after simplified as
$$
sum_ {I} = ^ Kx_itimes. 1 (N-a_i) = 0
$$
original statute problem: taking the least number from the set $ {N-a_i} $ (each number can take any number of times), so that their is zero.

We vertex and to set even according to the number of edges (if digital $ N-a_i $ set, and from the $ s $ and $ s + (N-a_i) $ connected edge).

Statute problem to: find length from 0 to 0 in the end of the smallest ring. BFS can be.

Optimization: N $ and $ a_i by known range: $ - 1000leq N-a_ileq 1000 $. Therefore, if the presence of start and end points of a ring 0, then we can reconstruct the order of the upper ring, so that each time after an edge, and are in the range [-1000,1000] a. So when we build map, and can range in [-1000,1000] inside.

Time complexity: $ O (E) = O (2001times max (1001, K)) $

Code

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
      
      
using namespace std;
const int MAX_N = 1e3 + 5;
const int offset = 1e3;
const int INF = 0x3f3f3f3f ;
int N, K;
bool has[MAX_N];
int d[MAX_N * 2];
vector< int> G[MAX_N * 2];
int (int s)
{
queue< int> que; que.push(s);
memset(d, 0x3f, sizeof d);
d[s] = 0;
while (!que.empty()) {
int v = que.front (); que.pop ();
for ( int i = 0; i < ( int)G[v].size(); ++i) {
int u = G[v][i];
if (u == s) {
return d[v] + 1;
} else if (d[u] == INF) {
d[u] = d[v] + 1;
que.push(u);
}
}
}
return INF;
}
int main()
{
cin >> N >> K;
for ( int i = 0; i < K; ++i) {
int a; scanf( "%d", &a);
has[a] = 1;
}
for ( int sum = -1000; sum <= 1000; ++sum) {
for ( int a = 0; a <= 1000; ++a) {
if (has[a]) {
int nxt = N - a + sum;
if ( -1000 <= nxt && nxt <= 1000) {
G[sum + offset].push_back(nxt + offset);
}
}
}
}
int ans = bfs( 0 + offset);
if (ans == INF) {
puts( "-1");
} else {
printf( "%dn", ans);
}
return 0;
}

Original: Big Box  Codeforces 789E


Guess you like

Origin www.cnblogs.com/chinatrump/p/11588885.html