Jury interpretation


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;

}

Tags: Algorithm C++ Dynamic Programming

Posted by dbchip2000 on Sat, 04 Jun 2022 01:48:24 +0530