<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Forum Pasja Informatyki - Najnowsze z tagiem problem_plecakowy</title>
<link>https://forum.pasja-informatyki.pl/tag/problem_plecakowy</link>
<description>Powered by Question2Answer</description>
<item>
<title>Zadanie waga z finału IX OI, przyśpieszenie dp, problem plecakowy, dynamik</title>
<link>https://forum.pasja-informatyki.pl/580900/zadanie-waga-z-finalu-ix-oi-przyspieszenie-dp-problem-plecakowy-dynamik</link>
<description>

&lt;p&gt;Mam problem z takim zadaniem:&amp;nbsp;&lt;a href=&quot;https://szkopul.edu.pl/problemset/problem/rM5z02XMy26GufAAAC03fjcB/site/?key=statement&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://szkopul.edu.pl/problemset/problem/rM5z02XMy26GufAAAC03fjcB/site/?key=statement&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Niewątpliwie narzuca się, że trzeba użyć problemu plecakowego. Napisałem kod na 18pkt, w O(N * K^2), gdzie K, to suma wszystkich przedmiotów. Na początku naliczam plecak, jakie sumy mogę osiągnąć, w O(N * K), potem idę po wszystkich sumach od góry, to jeśli mogę ją osiągnąć, to wywalam te przedmioty, którymi ją osiągnąłem, i odpalam drugi plecak, już bez tych przedmiotów. O(N * K^2), bo K razy odpalę plecak w O(N * K).&lt;/p&gt;



&lt;p&gt;Nie wiem jak to przyśpieszyć, ale mam pewien pomysł, nie wiem czy dobry, i też nie pełny, ale myślałem, żeby zamiast czy da się dojść, to naliczać dp - na ile sposobów moge osiągnąć daną sumę, i potem jak idę od góry po wszystkch k, to żeby nie puszczać od nowa plecaka, tylko wziać te n elementów, którymi robiłem tą sumę, i kulturalnie odjąć do dp z nich. Tylko sa 2 problemy:&lt;/p&gt;



&lt;p&gt;1 - Nie wiem, czy to działa, bo wygląda to podejrzanie&lt;/p&gt;



&lt;p&gt;2 - Wartości dp mogą być zbyt duże (wydaje mi się, ze nawet 2^N), więc mogą przekroczyć zasięg unsigned long long.&lt;/p&gt;



&lt;p&gt;Jak ma ktoś pomysł, czy mogę to tak zrobić, a jak nie to jakiś inny pomysł, to z góry dziekuję za pomoc!&lt;/p&gt;



&lt;p&gt;Kod w O(N * K^2), dający 18pkt:&lt;/p&gt;



&lt;pre class=&quot;brush:plain;&quot;&gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int n = 0, wczytana_liczba = 0;
int MAX_DP_SIZE = 0;
vector&amp;lt;int&amp;gt; liczby;
vector&amp;lt;int&amp;gt; wyn1;
vector&amp;lt;int&amp;gt; wyn2;

int main()
{
    // O(N * K * K)
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin &amp;gt;&amp;gt; n;
    for (int i = 0; i &amp;lt; n; ++i)
    {
        cin &amp;gt;&amp;gt; wczytana_liczba;
        liczby.push_back(wczytana_liczba);
        MAX_DP_SIZE += wczytana_liczba;
    }

    MAX_DP_SIZE++;
    bool dp1[MAX_DP_SIZE] = {false};
    int idx_poprzedniego[MAX_DP_SIZE] = {-1};

    dp1[0] = true;

    for (int i = 0; i &amp;lt; n; ++i)
    {
         for (int j = MAX_DP_SIZE; j &amp;gt;= 0; --j)
         {
             if (j + liczby[i] &amp;lt;= MAX_DP_SIZE)
             {
                  if (dp1[j] == true &amp;amp;&amp;amp; dp1[j+liczby[i]] == false)
                  {
                      dp1[j+liczby[i]] = true;
                      idx_poprzedniego[j+liczby[i]] = j;
                  }
             }
         }
    }

    for (int i = MAX_DP_SIZE / 2; i &amp;gt;= 1; --i)
    {
        if (dp1[i] == true)
        {
            wyn1.clear();
            wyn2.clear();
            int wsk = i;
            while(true)
            {
                if (idx_poprzedniego[wsk] == -1)
                    break;
                wyn1.push_back(wsk - idx_poprzedniego[wsk]);
                wsk = idx_poprzedniego[wsk];
            }

            bool dp2[MAX_DP_SIZE] = {false};
            int idx_poprzedniego2[MAX_DP_SIZE] = {-1};
            dp2[0] = true;

            int wystapienia[MAX_DP_SIZE] = {0};
            for (int j = 0; j &amp;lt; wyn1.size(); ++j)
                wystapienia[wyn1[j]]++;

            for (int j = 0; j &amp;lt; n; ++j)
            {
                if (wystapienia[liczby[j]] &amp;gt; 0)
                    wystapienia[liczby[j]]--;
                else
                {
                    for (int k = MAX_DP_SIZE; k &amp;gt;= 0; --k)
                    {
                        if (k + liczby[j] &amp;lt;= MAX_DP_SIZE)
                        {
                            if (dp2[k] == true &amp;amp;&amp;amp; dp2[k+liczby[j]] == false)
                            {
                                dp2[k+liczby[j]] = true;
                                idx_poprzedniego2[k+liczby[j]] = k;
                            }
                        }
                    }
                }
            }

            if (dp2[i] == true)
            {
                int wsk = i;
                while(true)
                {
                    if (idx_poprzedniego2[wsk] == -1)
                        break;
                    wyn2.push_back(wsk - idx_poprzedniego2[wsk]);
                    wsk = idx_poprzedniego2[wsk];
                }
                cout &amp;lt;&amp;lt; wyn1.size() &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; wyn2.size() &amp;lt;&amp;lt; '\n';
                for (int j = 0; j &amp;lt; wyn1.size(); ++j)
                    cout &amp;lt;&amp;lt; wyn1[j] &amp;lt;&amp;lt; &quot; &quot;;
                cout &amp;lt;&amp;lt; endl;
                for (int j = 0; j &amp;lt; wyn2.size(); ++j)
                    cout &amp;lt;&amp;lt; wyn2[j] &amp;lt;&amp;lt; &quot; &quot;;
                return 0;
            }
        }
    }

    cout &amp;lt;&amp;lt; &quot;0&quot; &amp;lt;&amp;lt; '\n';

    return 0;
}
&lt;/pre&gt;



&lt;p&gt;Z góry dziękuję za pomoc i poświęcony czas!&lt;/p&gt;</description>
<category>Algorytmy</category>
<guid isPermaLink="true">https://forum.pasja-informatyki.pl/580900/zadanie-waga-z-finalu-ix-oi-przyspieszenie-dp-problem-plecakowy-dynamik</guid>
<pubDate>Fri, 24 Feb 2023 14:44:53 +0000</pubDate>
</item>
</channel>
</rss>