百度之星1003 度度熊与邪恶大魔王

xiaoxiao2021-02-28  128

度度熊与邪恶大魔王

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 6 18

最重要的算法部分就是一个dp

for(int td=0; td<=maxd; td++) { for(int i=1; i<=maxHP; i++) { long long t = 0; bool flag=true; for(int j=0; j<m; j++) { if(ski[j].att<=0)continue; if(i-ski[j].att<=0) { if(t>ski[j].spend||flag) { t=ski[j].spend; flag = false; } } else if(flag||t>spe[i-ski[j].att][td]+ski[j].spend) { t=spe[i-ski[j].att][td]+ski[j].spend; flag = false; } } spe[i][td]=t; } for(int i=0; i<m; i++) ski[i].att--; }

赛后更新


根据题目的意思 可以用完全背包解决 ,然后看题目给出的数据大小,可以在计算时计算生命值从1-1000,防御值0-10的所有情况,然后将所有符合对应的情况的怪兽加起来,之后就得出了消耗的水晶数。

#include<bits/stdc++.h> #define MAX 1050 using namespace std; int n,m; long long int spe[MAX][11];// long long int num[MAX][11];//每种情况对应的怪兽数量num[100][2]为生命值是100 防御力为2的怪兽的数量 long long int ans; struct skill { int att,spend; } ski[MAX]; int main() { while(cin>>n>>m) { ans=0; memset(num,0,sizeof(num)); memset(spe,0,sizeof(spe)); int maxa=0,maxd=0,maxHP=0,a,b,k,p; for(int i=0; i<n; i++) { cin>>a>>b; num[a][b]++; maxHP = max(maxHP,a); maxd = max(maxd,b);//记录生命值和防御力的最大值 } for(int i=0; i<m; i++) { cin>>k>>p; ski[i].spend=k; ski[i].att=p; maxa = max(maxa,ski[i].att);//记录技能伤害的最大值 } if(maxa<=maxd) {//技能伤害的最大值如果比防御力小则一定不能全部消灭,直接进行下一轮 cout<<-1<<endl; continue; } for(int td=0; td<=maxd; td++) { for(int i=1; i<=maxHP; i++) {//枚举所有情况 只需判断生命值小于最大值、防御力小于最大值的即可 long long t = 0; bool flag=true; for(int j=0; j<m; j++) {//完全背包 if(ski[j].att<=0)continue; if(i-ski[j].att<=0) { if(t>ski[j].spend||flag) { t=ski[j].spend; flag = false; } }else if(flag||t>spe[i-ski[j].att][td]+ski[j].spend) { t=spe[i-ski[j].att][td]+ski[j].spend; flag = false; } } spe[i][td]=t; } for(int i=0;i<m;i++) ski[i].att--;//每次防御相同的怪兽枚举完时,将攻击力减少1 其实就是相当于攻击被防御抵消掉一部分 } for(int i=0; i<=maxHP; i++) { for(int j=0; j<=10; j++) { ans+=(spe[i][j]*num[i][j]);//将所有的消耗累加 } } cout<<ans<<endl; } return 0; }
转载请注明原文地址: https://www.6miu.com/read-24571.html

最新回复(0)