shape
state
surface
show
:
f
[
i
]
[
j
]
[
k
]
:
from
front
i
individual
people
in
pick
choose
Yes
j
individual
people
,
And
yes
answer
of
Argue
square
total
branch
and
control
square
total
branch
of
difference
value
by
k
,
of
most
large
total
branch
Status representation: f[i][j][k]: the maximum total score of J selected from the previous I, and the difference between the total score of the defense and the total score of the prosecution is k
Status representation: f[i][j][k]: the maximum total score of J selected from the previous I, and the difference between the total score of the defense and the total score of the prosecution is k
shape
state
turn
shift
square
Process
:
State transition equation:
State transition equation:
f
[
i
,
j
,
k
]
=
{
f
[
i
−
1
]
[
j
]
[
k
]
(
no
choose
Select
i
)
f
[
i
−
1
,
j
−
1
,
k
−
(
d
[
i
]
−
p
[
i
]
)
]
(
choose
Select
Yes
i
)
F[i, J, k]=\left\{\begin{matrix} f[i-1][j][k] (do not select i) \ f[i-1,j-1,k-(d[i]-p[i])] (select i) \end{matrix} \right
f[i,j,k]={f[i − 1][j][k] (I is not selected) f[i − 1,j − 1,k − (d[i] − p[i])] (I is selected)
**Points easy to make mistakes: * * during pretreatment, all
j
=
=
1
j==1
j==1, which is easier to handle.
**Why should it be handled separately** For example, the following figure
I
Men
stay
enter
that 's ok
d
p
of
Hour
Wait
,
want
interview
ask
reach
During dp, we need to access
During dp, we need to access j-1
,
also
Just
yes
0
yes
have
can
can
cover
interview
ask
of
,
but
yes
choose
Select
0
individual
yes
no
cover
set
righteousness
of
,
because
this
need
want
single
single
place
reason
.
That is, 0 may be accessed, but 0 is undefined, so it needs to be processed separately.
That is, 0 may be accessed, but 0 is undefined, so it needs to be processed separately.
I Men still need want Examination Consider yes no can enough enter that 's ok f [ i , j , k ] = f [ i − 1 , j , k ] What Do Hour Wait no can enter that 's ok this step And ? When root book nothing method from front i − 1 individual people in nothing method take Out j individual people of Hour Wait We also need to consider whether we can perform f[i,j,k]=f[i-1,j,k] and when we can not perform this step\ When it is impossible to take out j people from the previous I-1 people We also need to consider whether f[i,j,k]=f[i − 1,j,k] can be carried out, and when can this step not be carried out? When it is impossible to remove j people from the previous I − 1 people
So we need to add a p_ The num array stores the number of individuals taken from dp at each step
When traversing the tolerance, it is also necessary to determine whether this person can be added, that is, k-sub_ Whether Val is legal
most
after
look for
reach
solution
Decide
square
case
:
I
Men
before
see
one
lower
Deliver
PUSH
of
common
type
Finally, we find the solution: let's first look at the recursive formula
Finally, we find the solution: let's first look at the recursive formula
f
[
i
,
j
,
k
]
=
{
f
[
i
−
1
,
j
,
k
]
(
choose
Select
Yes
i
)
f
[
i
−
1
,
j
−
1
,
k
−
(
d
[
i
]
−
p
[
i
]
)
]
+
p
[
i
]
+
d
[
i
]
(
no
have
choose
Select
i
)
f[i,j,k]=\left\{\begin {matrix} f[i-1,j,k] (I selected) \ \ f[i-1, J-1, k- (d[i]-p[i])]+p[i]+d[i] (I not selected) \end{matrix} \right
f[i,j,k]={f[i − 1,j,k] (I selected) f[i − 1,j − 1,k − (d[i] − p[i])]+p[i]+d[i] (I not selected)
as
fruit
f
[
n
,
m
,
f
i
n
a
l
k
]
!
=
f
[
n
,
m
,
f
i
n
a
l
k
]
,
say
bright
Yes
take
reach
Yes
Section
n
individual
If f[n, m, final_k]= F[n, m, final \uk] indicates that the nth
If f[n, m, final]= F[n, m, final], indicating that the nth
because
this
I
Men
inverted
too
come
Times
calendar
Just
that 's ok
,
notes
meaning
k
and
j
of
more
new
So let's just iterate backwards and note the update of k and j
So let's just iterate backwards and note the update of k and j
yes Yes , stay first beginning turn number group of Hour Wait , no want and close method of number group value punching Protuberance , no be very hard Distinguish recognize . than as most after one second carry hand over of Hour Wait I w a Yes one hair , because by I hold his in two individual number group first beginning turn by 0 , stay transport enter of value by whole 0 of Hour Wait Just meeting wrong error , change become m e m s e t − 1 Just good Yes By the way, when initializing the array, do not conflict with the legal array values, otherwise it is difficult to identify\ For example, in the last submission, I made a wa, because I initialized two of the arrays to 0 \ \, and an error will occur when the input value is all 0. Just change it to memset -1 By the way, when initializing the array, do not conflict with the legal array values, otherwise it is difficult to identify. For example, in the last submission, I made a wa. Because I initialized two arrays to 0, an error will occur when the input value is all 0. Just change it to memset − 1
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 200 + 5; int p[N]; int d[N]; int f[N][22][800 + 5]; int p_num[N][22][800 + 5]; int n, m; int base = 400; int start; int score_d; int score_p; int final_k; stack<int>id; void init() { score_p = 0; score_d = 0; final_k = 0; while (!id.empty()) { id.pop(); } memset(p, 0, sizeof p); memset(d, 0, sizeof d); memset(f, -1, sizeof f); memset(p_num, 0, sizeof p_num); } int getIndex(int val) { return val + 400; } int validSub(int val) { return val >= -400 && val <= 400; } void print() { cout << "Jury #" << ++start << endl; cout << "Best jury has value " << score_p << " for prosecution and value " << score_d << " for defence:" << endl; while (!id.empty()) { cout << " "; cout << id.top(); id.pop(); } cout <<"\n\n"; } signed main() { while (cin >> n >> m, n || m) { init(); for (int i = 1; i <= n; i++) { cin >> p[i] >> d[i]; } for (int i = 1; i <= n; i++) { for (int k = -400; k <= 400; k++) { int sub = d[i] - p[i]; int index = getIndex(k); f[i][1][index] = f[i - 1][1][index]; p_num[i][1][index] = p_num[i - 1][1][index]; if (sub == k && d[i] + p[i] > f[i][1][index]) { f[i][1][index] = d[i] + p[i]; p_num[i][1][index] = 1; } } } for (int i = 2; i <= n; i++) { for (int j = 2; j <= min(i, m); j++) { for (int k = -400; k <= 400; k++) { if (i == 3 && j == 2 && k == -2) { cout << ""; } int index = getIndex(k); if (p_num[i - 1][j][index] == j) { f[i][j][index] = f[i - 1][j][index];//Unselect i p_num[i][j][index] = p_num[i - 1][j][index];//Unselect i } int sub_val = d[i] - p[i]; if (validSub(k - sub_val))//Select i { if (p_num[i - 1][j - 1][getIndex(k - sub_val)] == j - 1 && f[i - 1][j - 1][getIndex(k - sub_val)] + p[i] + d[i] > f[i][j][index]) { f[i][j][index] = f[i - 1][j - 1][getIndex(k - sub_val)] + p[i] + d[i]; p_num[i][j][index] = p_num[i - 1][j - 1][getIndex(k - sub_val)] + 1; } } } } } for (int sub = 0; sub <= 400; sub++) { int index1 = base + sub; int index2 = base - sub; if (p_num[n][m][index1] == m || p_num[n][m][index2] == m) { if (p_num[n][m][index1] == m && p_num[n][m][index2] == m) { final_k = f[n][m][index1] > f[n][m][index2] ? sub : -sub; } else { final_k = ((p_num[n][m][index1] == m) ? sub : -sub); } break; } } // cout << final_k; int choose_num = m; int temp_k = final_k; for (int i = n; i; i--) { int index = getIndex(temp_k); if (f[i][choose_num][index] != f[i - 1][choose_num][index]) { score_p += p[i]; score_d += d[i]; id.push(i); choose_num--; temp_k -= (d[i] - p[i]); } } print(); } return 0; }