Level Up - ICPC Southeastern Europe Contest 2019(簡單DP)

 

 

 

題意:Steve玩魔獸世界要作任務升兩級,任務在你不一樣的等級給的經驗不一樣,輸入任務數量和升第一級和升第二級須要的經驗,接着輸入每一個任務第一級完成給的經驗和花費的時間、第二級級完成給的經驗和花費的時間。求要升兩級最少要花多少時間,若是不能則輸出-1。node

題解:ios

由題目數據能夠直接想到用動態規劃來作,由於最多須要的經驗只有五百,所以能夠開DP[I][J][K](記得開爲long long,INF也得更換,我由於這個卡了好久),i表明第一級的經驗,J表明第二級的經驗,K表明第幾個任務。具體見代碼註釋。spa

 

#define _CRT_SECURE_NO_DepRECATE
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>
#include <algorithm>
#include <bitset>
#include <cstdlib>
#include <cctype>
#include <iterator>
#include <vector>
#include <cstring>
#include <cassert>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#define ll long long
#define INF 0x3f3f3f3f
#define ld long double
const ld pi = acos(-1.0L), eps = 1e-8;
int qx[4] = { 0,0,1,-1 }, qy[4] = { 1,-1,0,0 }, qxx[2] = { 1,-1 }, qyy[2] = { 1,-1 };
using namespace std;
struct node
{
    ll exp1, exp2, time1, time2;//一級的經驗 兩級的經驗 一級消耗的時間 兩級消耗的時間
}ren[510];
ll dp[511][511];
bool cmp(node a, node b)
{
    return a.exp1 < b.exp1;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll a, b, c;
    cin >> a >> b >> c;
    ll ans = 0;
    for (ll i = 0; i <= 510; i++)
    {
        for (ll f = 0; f <= 510; f++)
        {
            dp[i][f] = numeric_limits<int64_t>::max();//初始化,注意是longlong!
        }
    }
    for (ll i = 0; i < a; i++)
    {
        cin >> ren[i].exp1 >> ren[i].time1 >> ren[i].exp2 >> ren[i].time2;
    }
    sort(ren, ren + a, cmp);//先將任務按照第一級經驗的大小進行排序,不然易出bug
    dp[0][0] = 0;
    for (ll i = 0; i < a; i++)
    {
        for (ll f = b; f >= 0; f--)
        {
            for (ll k = c; k >= 0; k--)
            {
                if (dp[f][k] == numeric_limits<int64_t>::max())
                {
                    continue;
                }
                if (f < b)//若是還沒到第二級
                {
                    ll exp1 = f + ren[i].exp1, exp2 = k;
                    if (exp1 > b)//升級時溢出的經驗會保留
                    {
                        exp2 = min(c, exp1 - b + k);//避免溢出的經驗再溢出
                        exp1 = b;
                    }
                    dp[exp1][exp2] = min(dp[exp1][exp2], dp[f][k] + ren[i].time1);//狀態轉移
                }
                ll exp2 = min(k + ren[i].exp2, c);//避免溢出
                dp[f][exp2] = min(dp[f][exp2], dp[f][k] + ren[i].time2);//狀態轉移
            }
        }
    }
    if (dp[b][c] == numeric_limits<int64_t>::max())//判斷是否有解
    {
        cout << "-1";
        return 0;
    }
    cout << dp[b][c];
    return 0;
}
相關文章
相關標籤/搜索