ICPC Southeastern Europe Contest 2019 B. Level Up(DP)

Link to the
topic The main idea of ​​the topic:
There are two levels in total, there are n tasks, each task has the experience value obtained at the first level and the required time, and each task also has the experience obtained at the second level Value and time required. The extra experience after the first level upgrade is put into the second level. Q. What is the minimum time required to advance to two levels? If not, it outputs -1.

Problem-solving ideas:
define dp [i] [j] to obtain the minimum time required for the first-level experience to be i and the second-level experience to be j. Consider using the 01 knapsack to solve in reverse order to reduce this dimension of the first few tasks.
Important: The first level of experience needs to be sorted in ascending order, otherwise the order will affect the dp result. If the first level of experience is: 90,40,40, and the first level of experience required is 100, then the overflow situation is only 130, but 40,40,90 has 40 + 90 = 130,40 + 40 + 90 = 170 two cases, so sort in ascending order, otherwise there will be omissions.

Problem solving code:

#include<bits/stdc++.h>
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const ll maxn=2e5+10;
ll inf=1e18;
ll dp[1010][1010];
struct E{
    int x,t,y,r;
}p[505];
bool cmp(E a1,E a2)
{
    return a1.x<a2.x;
}
int main()
{
    ll n,s1,s2;
    cin>>n>>s1>>s2;
    for (ll i=0;i<=1000;i++)
    {
        for (ll j=0;j<=1000;j++)
        dp[i][j]=inf;
    }
    dp[0][0]=0;
    for (ll i=1;i<=n;i++)
    {
        cin>>p[i].x>>p[i].t>>p[i].y>>p[i].r;
    }
    sort(p+1,p+1+n,cmp);
    for (ll i=1;i<=n;i++)
    {
        for (ll j=1000;j>=0;j--)
        {
            for (ll k=1000;k>=0;k--)
            {
                ll t1=inf,t2=inf;
                if (j>=p[i].x && j-p[i].x<s1)
                t1=dp[j-p[i].x][k]+p[i].t;

                if (k>=p[i].y)
                t2=dp[j][k-p[i].y]+p[i].r;
             
                dp[j][k]=min(dp[j][k],min(t1,t2));
            }
        }
    }
    ll ans=inf;
    for (ll j=s1;j<=1000;j++)
    {
        for (ll k=max(0ll,s2-(j-s1));k<=1000;k++)
        {
            ans=min(ans,dp[j][k]);
        }
    }
    if (ans==inf)
    ans=-1;
    cout<<ans;
    return 0;
}
Published 12 original articles · Like1 · Visits 327

Guess you like

Origin blog.csdn.net/qq_41818939/article/details/105527105