HDU6082度度熊与邪恶大魔王
来源:互联网 发布:java反射例子 编辑:程序博客网 时间:2024/04/29 05:00
HDU6082度度熊与邪恶大魔王
标签:DP,背包问题
http://www.sakurasake.icoc.me/nd.jsp?id=10
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
Source
2017"百度之星"程序设计大赛 - 资格赛
分析:
这题明显是个背包问题,但是仔细观察,发现用完全背包最正常的写法时间复杂度为O(n*m),肯定TLE,所以优化。看题目给出的数据大小,可以在计算时计算生命值从1-1000,防御值0-10的所有情况,然后将所有符合对应的情况的怪兽加起来,计算出消耗最小的晶石数量
具体一点说:把怪兽的生命值当成背包的体积,每个技能的伤害值当成每个物品的大小,每个技能的晶石数当成这个物品的花费,目的是把每个背包填满或更多,求每个背包的最小花费就可以了
对于第u个技能来说,如果p[u]<=j,说明根本打不出伤害,不用管。
反之,伤害则temp=p[u]-j这时候 又有两种情况:
如果temp>=j,说明靠这一个技能就够打出足够伤害了,那么肯定是用消耗晶石最少的那个技能
F[i][j]表示消灭生命力为i,防御值为j的怪物需要最小的晶石数
状态转移方程为:F[i][j]=min(f[i-(p[num]-j)][j]+k[num];
参考代码如下:
#include<bits/stdc++.h>#define LL long longusing namespace std;inline LL read(){LL f=1,x=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}const int maxn=100005;const int maxm=1005;LL a[maxn],b[maxn],k[maxm],p[maxm];LL f[maxm][15];inline LL max(LL a,LL b){return a>b?a:b;}inline LL min(LL a,LL b){return a<b?a:b;}int main(){LL n,m;while(scanf("%lld%lld",&n,&m)!=EOF){LL up1=0,up2=0,hp=0;for(int i=1;i<=n;i++){a[i]=read(),b[i]=read();up1=max(up1,b[i]);hp=max(hp,a[i]);}for(int i=1;i<=m;i++){k[i]=read(),p[i]=read();up2=max(up2,p[i]);}if(up1>=up2){cout<<"-1\n";continue;}memset(f,0,sizeof(f)); for(int i=1;i<=hp;i++)//穷举每个幽灵生命值--相当于背包中的总重量 for(int j=0;j<=10;j++)//穷举每个幽灵防御值 { f[i][j]=1e18; for(int num=1;num<=m;num++)//num魔法的序号,使用第num 个魔法:1.2..m { LL temp=p[num]-j;//算:伤害值-防御值 if(temp<=0)continue;//魔法不管用,继续使用下一个魔法 if(temp>=i)f[i][j]=min(f[i][j],k[num]);//如果第num魔法》=生命值i,那一招打死,最小能量为 //自己和k[num],第num else f[i][j]=min(f[i][j],f[i-temp][j]+k[num]);//否则看本身的小还是使用生命值减少+消耗能量 } } LL ans=0;//把n个幽灵全部打死:第一个幽灵f[a[1][b[1]]);第2个幽灵f[a[2][b[2]]); for(int i=1;i<=n;i++)ans+=f[a[i]][b[i]]; cout<<ans<<endl;}return 0;}
And else 在别处看到了这个题的另一个包装
实质上都是同一个问题,无区别
-------------------------------------------------------------------------------
恶魔城是一款风靡全亚洲的rpg游戏,游戏的设定是这样的:
你控制的主角叫贝尔蒙特,你需要打败恶魔城中的 n个幽灵才能获得最终的胜利,每个幽灵有生命值a[i]和魔法护盾防御值b[i]。贝尔蒙特一共有m种魔法攻击,第i种魔法需要消耗能量k[i],造成p[i]点伤害。
如果贝尔蒙特使用第i种魔法打在第j个幽灵身上,会使得第j个幽灵的生命值减少p[i]-b[j], 当然如果伤害小于魔法护盾,那么攻击就不会奏效。如果幽灵的生命值降为0或以下,那么就会被消灭。
每个魔法可以无限次使用,请问贝尔蒙特最少消耗多少能量,就可以消灭所有幽灵。
输入描述 Input Description
多组测试数据
每组数据第一行两个整数n,m(表示n个幽灵,m种魔法)。
接下来n行,每行两个整数a[i],b[i],分别表示幽灵的生命值和魔法护盾值。
接下来m行,每行两个整数k[i],p[i],分别表示第i种魔法消耗的能量值和造成的伤害值。
输出描述 Output Description
对于每组测试数据,输出最小的能量消耗,如果不能击败所有的幽灵,输出-1。
样例输入 Sample Input
1 2
3 5
7 10
6 8
1 2
3 5
10 7
8 6
样例输出 Sample Output
6
18
数据范围及提示 Data Size & Hint
40%数据:
1<=n<=100
1<=m<=100
1<=a[i]<=100
0<=b[i]<=10
0<=k[i]<=1000
0<=p[i]<=100
100%数据
1<=n<=100000
1<=m<=1000
1<=a[i]<=1000
0<=b[i]<=10
0<=k[i]<=100000
0<=p[i]<=1000
数据来源 Source
2017年暑假包河区初中组测试
- Hdu6082 度度熊与邪恶大魔王
- hdu6082-度度熊与邪恶大魔王
- HDU6082-度度熊与邪恶大魔王
- HDU6082-度度熊与邪恶大魔王
- HDU6082度度熊与邪恶大魔王
- hdu6082 2017"百度之星"资格赛1003 度度熊与邪恶大魔王(完全背包dp)
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王
- 1003 度度熊与邪恶大魔王
- 度度熊与邪恶大魔王(DP)
- iOS下的 Fixed + Input 调用键盘的时候fixed无效问题解决方案
- Robotframework(3):使用pycharm编写和运行RF脚本
- 设置Tomcat的UTF-8编码
- Xamarin.Forms——本地数据库Realm入门
- 对抗样本和对抗网络
- HDU6082度度熊与邪恶大魔王
- codeigniter CLI 命令模式下运行
- C/C++: 操作符重载案例
- rhel7-firewalld端口转发
- ionic cordova使用笔记
- Hadoop表连接问题
- java后端1年经验和技术总结(1)
- MySQL表默认排序问题
- mac下修改权限