码迷,mamicode.com
首页 > 其他好文 > 详细

ICPC山东省赛 H.Adventurer's Guild

时间:2021-05-24 08:30:55      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:type   code   tps   com   集合   include   ios   思路   必须   

题目链接:Adventurer‘s Guild

  • 题意:主角拥有H值和S值,每个怪兽有一个h值hi和s值si,消灭一个怪兽主角需要花费hi和si,此时主角的H值变为H-hi,S值变为S-si,若S值不够减si,可以拿H值进行替补,但必须保证H值始终大于0,消灭一个怪兽会得到w的价值,求最大w之和。

  • 思路:01背包变型 + 滚动数组优化

  • 解析:

    1. 集合划分:dp[i][j][k]表示前i个怪兽消耗j的h值和k的s值可获得最大w。
    2. 状态表示:
      1. 不选择第i个怪兽:dp[i][j][k] = dp[i-1][j][k]
      2. 当 j > a[i].h && j + k > a[i].h + a[i].s(主角的H值 > 该怪兽的h值并且主角的H值 + S值得 > 该怪兽的h值 + s值)ps: 不能写成j > a[i].h && j + k > a[i].s(因为若此时主角的S值小于怪兽的s值,则需要H给S进行替补,替补后可能H就小于h,此时H可能小于等于0不满足题目条件)
        选择第i个怪兽:[注意防止数组越界]
        dp[i-1][j-a[i].h][k-a[i].s] + a[i].w)(k >= a[i].s)
        dp[i-1][j - a[i].h - (a[i].s - k)][0] + a[i].w)(k < a[i].s)
  • 代码:

#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1005;
const int M = 305;
ll dp[N][M][M];
ll n, h, s;
struct Node
{
    ll h, s, w;
}a[N];
int main()
{
    cin >> n >> h >> s;
    for(int i = 1; i <= n; i++)
        cin >> a[i].h >> a[i].s >> a[i].w;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= h; j++)
        {
            for(int k = 0; k <= s; k++)
            {
                dp[i][j][k] = dp[i-1][j][k];
                if(j > a[i].h && j + k > a[i].s + a[i].h)
                {
                    if(k >= a[i].s) dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-a[i].h][k-a[i].s] + a[i].w);
                    else dp[i][j][k] = max(dp[i][j][k], dp[i-1][j - a[i].h - (a[i].s - k)][0] + a[i].w);
                }
            }
        }
    }
    cout << dp[n][h][s] << endl;
    return 0;
}

但是上面的代码会MLE,所以用滚动数组的思想进行优化成二维数组即可。

  • 代码:
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1005;
const int M = 305;
ll dp[M][M];
ll n, h, s;
struct Node
{
    ll h, s, w;
}a[N];
int main()
{
    cin >> n >> h >> s;
    for(int i = 1; i <= n; i++)
        cin >> a[i].h >> a[i].s >> a[i].w;
    for(int i = 1; i <= n; i++)
    {
        for(int j = h; j > a[i].h; j--)
        {
            for(int k = s; k >= 0; k--)
            {
                if(j + k > a[i].s + a[i].h)
                {
                    if(k >= a[i].s) dp[j][k] = max(dp[j][k], dp[j-a[i].h][k-a[i].s] + a[i].w);
                    else dp[j][k] = max(dp[j][k], dp[j - a[i].h - (a[i].s - k)][0] + a[i].w);
                }
            }
        }
    }
    cout << dp[h][s] << endl;
    return 0;
}

ICPC山东省赛 H.Adventurer's Guild

标签:type   code   tps   com   集合   include   ios   思路   必须   

原文地址:https://www.cnblogs.com/K2MnO4/p/14766622.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!