HDU 2159 FATE by Assassin
来源:互联网 发布:pop3使用的端口号 编辑:程序博客网 时间:2024/06/05 15:20
Problem Description
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能升掉这最后一级吗?
Input
输入数据有多组,对于每组数据第一行输入n,m,k,s(0 < n,m,k,s < 100)四个正整数。分别表示还需的经验值,保留的忍耐度,怪的种数和最多的杀怪数。接下来输入k行数据。每行数据输入两个正整数a,b(0 < a,b < 20);分别表示杀掉一只这种怪xhd会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)
Output
输出升完这级还能保留的最大忍耐度,如果无法升完这级输出-1。
Sample Input
10 10 1 10
1 1
10 10 1 9
1 1
9 10 2 10
1 1
2 2
Sample Output
0
-1
1
思路:
网上好多说用三层循环就行了,化为二维背包问题,他们的思路是
二维完全背包,第二层跟第三层的要顺序循环;(0-1背包逆序循环);状态可理解为,在背包属性为 {m(忍耐度), s(杀怪个数)} 里最多能得到的经验值,之前的背包牺牲体积,这个背包牺牲忍耐度跟个数
注意: 最后扫的时候 外层循环为忍耐度,内层循环为杀怪个数,因为题目要求出剩余忍耐度最大,没有约束杀怪个数,一旦找到经验加满的即为最优解;
状态转移方程为: f[j][k]=max(f[j][k],f[j-v[i]][k-1]+w[i]); w[i]表示杀死第i个怪所得的经验值,v[i]表示消耗的忍耐度
看起来并不需要用三层循环,我们构造一个结构体就好了!
结构体为dp[i]代表如果前i种敌人随便杀,value代最大可以得到的价值,即使完全背包问题,num代表此时杀了多少个怪物。
我们用两层for循环,第一层for(i=1;i<=k;i++)代表随便杀上前i种怪物
第二层for(j=1;j<=m;j++)完全背包,,value代表在忍耐度为j(随便杀前i种怪物)的情况下最多得到多的价值,注意更新条件,价值更新变大及其顺便更新杀敌数目!
核心代码
for(i=1;i<=k;i++) { for(j=1;j<=m;j++) //表示这么多忍耐范围内可以得到少经验 ,完全背包 { if(j>=data[i][1]&&dp[j-data[i][1]].value+data[i][0]> dp[j].value) { dp[j].value=dp[j-data[i][1]].value+data[i][0]; dp[j].num=dp[j-data[i][1]].num+1; } } }
最后从1到m内输出 m-第一个价值大于等于n且杀敌数小于等于s的位置
讲的不是太好。。。下面看代码。。。
#include<bits/stdc++.h>#define input freopen("input.txt","r",stdin)using namespace std;typedef struct node{ int num; int value; }node;node dp[1000];int data[1000][2]; // data[i][0]表示可以得到的经验,data[i][1]表示 消耗的耐心程度 int main(){ input; int n,m,k,s; int i,j,flag; while(cin>>n>>m>>k>>s) { memset(dp,0,sizeof(dp)); for(i=1;i<=k;i++) { cin>>data[i][0]>>data[i][1]; } for(i=1;i<=k;i++) { for(j=1;j<=m;j++) //表示这么多忍耐范围内可以得到少经验 ,完全背包 { if(j>=data[i][1]&&dp[j-data[i][1]].value+data[i][0]> dp[j].value) { dp[j].value=dp[j-data[i][1]].value+data[i][0]; dp[j].num=dp[j-data[i][1]].num+1; } } } for(flag=0,i=1;i<=m;i++) { if(dp[i].value>=n&&dp[i].num<=s) { cout<<(m-i)<<endl; flag=1; break; } } if(flag==0)cout<<-1<<endl; } return 0;}
- HDU 2159 FATE by Assassin
- HDU 2955 Robberies by Assassin
- HDU 2571 命运 by Assassin
- HDU 5965 扫雷 By Assassin
- HDU 1506 City Game by Assassin
- HDU 1069 Monkey and Banana by Assassin
- HDU 2487 Ugly Windows By Assassin
- HDU 2489 Minimal Ratio Tree By Assassin
- HDU 1054 Strategic Game By Assassin
- HDU 5927 Auxiliary Set By Assassin
- HDU 2686 Matrix By Assassin 多线程dp
- HDU 3001 Travelling By Assassin 3进制状压
- hdu 2159 FATE
- hdu 2159 FATE
- hdu 2159 FATE
- HDU 2159 - FATE
- hdu 2159 FATE
- HDU 2159 FATE
- 我的第一篇博客
- 跟踪_纪中4805_bfs
- 分布式缓存的一致性Hash算法
- 288_自定义View测量模式
- 我是男友的R小帮手
- HDU 2159 FATE by Assassin
- redis 安装 随笔
- SDUTACM 数据结构实验之链表九:双向链表
- hihocoder1385 A Simple Job JAVA String split 字符串切割
- 初识Linux内核-和CMOS打电话
- 第一章 算法在计算中的作用
- 289_自定义小进度条
- 一起来学activeMQ 5.pub/sub ,non-persistent/persistent,queue
- 确定字符互异