打怪兽

来源:互联网 发布:java转义字符 编辑:程序博客网 时间:2024/04/30 00:08

题目来源
Accepts: 3608 Submissions: 22145 
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) 
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 2 
3 5 
7 10 
6 8 
1 2 
3 5 
10 7 
8 6 
Sample Output 

18 


#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>


#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int maxn=100000+5;
const int maxm=1000+5;


LL a[maxn],b[maxn];
LL k[maxm],p[maxm];
LL dp[maxm][15];//防御力为j,打出i点伤害以上时所需的最少晶石


LL max(LL a,LL b)
{
    return a>b?a:b;
}
LL min(LL a,LL b)
{
    return a<b?a:b;
}




int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        LL up1=0,up2=0,hp=0;
        for(int i=0; i<n; i++)
        {
            scanf("%I64d%I64d",&a[i],&b[i]);
            up1=max(up1,b[i]);
            hp=max(hp,a[i]);
        }


        for(int i=0; i<m; i++)
        {
            scanf("%I64d%I64d",&k[i],&p[i]);
            up2=max(up2,p[i]);
        }
        if(up1>=up2)
        {
            printf("-1\n");
            continue;
        }
        mem(dp,0);
        for(int i=0; i<=10; i++)//防御
        {
            for(int j=1;j<=hp;j++)//造成伤害值
            {
                dp[j][i]=1e18;
                for(int u=0;u<m;u++)//第u个技能
                {
                    LL dmg=p[u]-i;//第u个技能能造成的伤害
                    if(dmg<=0)
                        continue;
                    if(dmg>=j)
                    {
                        dp[j][i]=min(dp[j][i],k[u]);
                    }
                    else
                    {
                        dp[j][i]=min(dp[j][i],dp[j-dmg][i]+k[u]);
                    }
                }
            }
        }
        LL ans=0;
        for(int i=0;i<n;i++)
        {
            ans+=dp[a[i]][b[i]];
        }
        printf("%I64d\n",ans);


    }
    return 0;
}

原创粉丝点击