2017百度之星资格赛 1003 度度熊与邪恶大魔王(完全背包)

来源:互联网 发布:mac vlc流媒体服务器 编辑:程序博客网 时间:2024/04/28 15:34

度度熊与邪恶大魔王

Accepts: 2016
Submissions: 12307
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others) 

传送门:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=774&pid=1003

Problem Description

度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来。

邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力。

度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石,造成p[i]点伤害。

当然,如果度度熊使用第i个技能打在第j个怪兽上面的话,会使得第j个怪兽的生命值减少p[i]-b[j],当然如果伤害小于防御,那么攻击就不会奏效。

如果怪兽的生命值降为0或以下,那么怪兽就会被消灭。

当然每个技能都可以使用无限次。

请问度度熊最少携带多少晶石,就可以消灭所有的怪兽。

Input

本题包含若干组测试数据。

第一行两个整数n,m,表示有n个怪兽,m种技能。

接下来n行,每行两个整数,a[i],b[i],分别表示怪兽的生命值和防御力。

再接下来m行,每行两个整数k[i]和p[i],分别表示技能的消耗晶石数目和技能的伤害值。

数据范围:

1<=n<=100000

1<=m<=1000

1<=a[i]<=1000

0<=b[i]<=10

0<=k[i]<=100000

0<=p[i]<=1000

Output

对于每组测试数据,输出最小的晶石消耗数量,如果不能击败所有的怪兽,输出-1

Sample Input
1 23 57 106 81 23 510 78 
Sample Output
8
16
Aceppted代码
/*Problem:度度熊与邪恶大魔王Author:QiZhaoData:2017-08-05Description:DP,完全背包Copyright  2017 QiZhao. All rights reserved.*/#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1020;const ll INF=0x3f3f3f3f;ll num[maxn][12];//防御值为j,生命值为i的怪物的个数ll dp[1020][15];//对于生命值为i,防御值为j的怪物所消耗的最小水晶数struct skill{    ll hit;    ll price;} a[maxn];ll best[maxn];//攻击力为i时,消耗的最少水晶数。ll min(ll a,ll b){    if(a>b)        return b;    else        return a;    }    void complete_packet(int k, int p)//p为攻击力,k为消耗水晶数{    for (int b = 0; b <= 10; ++b)    {        if (b >= p)        {            continue;        }        else        {            int d = p - b;            //血量小于攻击            for (int a = 1; a <= d; ++a)            {                dp[a][b] = min(dp[a][b], k);            }            //血量大于攻击            for (int a = d + 1; a <= 1000; ++a)            {                dp[a][b] = min(dp[a][b], dp[a - d][b] + k);            }        }    }}int main(){    cin.sync_with_stdio(false);    ll n, m;    ll x, y;    ll /*max_hp = -0xffff,*/ max_def = -INF, max_hit = -INF;    while(cin >> n >> m)    {        max_def = -INF, max_hit = -INF;        memset(num, 0, sizeof(num));        memset(a, 0, sizeof(a));        memset(best, -1, sizeof(best));        memset(dp, 0, sizeof(dp));        for(ll i = 0; i < n; i++)        {            cin >> x >> y;            num[x][y]++;            //if(x >= max_hp)            //max_hp = x;            if(y >= max_def)                max_def = y;        }        ll flag = 0;        for(ll i = 0; i < m; i++)        {            cin >> x >> y;            if(best[y] == -1)            {                a[flag].hit = y;                a[flag].price = x;                best[y] = x;                if(a[flag].hit > max_hit)                    max_hit = a[flag].hit;                flag++;            }            else            {                if(x < best[y])                    best[y] = x;            }        }        ll ans = 0;        ll temp = 0; //记录已处理怪物个数,优化时间        if(max_def >= max_hit)            cout << "-1" << endl;        else        {            for (int i = 0; i <= 1010; ++i)//初始化DP            {                for (int j = 0; j <= 10; ++j)                {                    if (i == 0)                    {                        dp[i][j] = 0;                    }                    else                    {                        dp[i][j] = INF;                    }                }            }            for(int i=0;i<flag;i++)                complete_packet(best[a[i].hit],a[i].hit);            for(ll i = 0; i < 1002; i++)            {                if(temp == n)//优化时间                    break;                for(ll j = 0; j < 12; j++)                {                    if(num[i][j] != 0)                    {                        temp += num[i][j];                        ans += dp[i][j]*num[i][j];                    }                }            }            cout << ans << endl;        }    }    return 0;}

阅读全文
0 0
原创粉丝点击