HDU2159 FATE,二维背包+完全背包

来源:互联网 发布:arp绑定与mac绑定区别 编辑:程序博客网 时间:2024/05/23 01:12

一个简单二维背包问题。主要思想:通过二维矩阵mapa[j][i]求解,横坐标代表耐力值,纵坐标代表经验值。con代表当前所能获得的最大经验值1.初始化mapa[0][0]到mapa[m][N]为0。con为0。2.初始情况下仅有mapa[m][0]= s ;即已获得零点经验,还剩m点耐力,还能杀s只怪。3.读入一个怪的信息(经验值a ,耐力b ),而后遍历第0到第con列的每一个单元,当满足:①mapa[j][i]>0(代表还可以杀怪)。②j-b>=0(代表杀此怪的耐力足够)③mapa[j-b][i+a]<=mapa[j][i]-1(代表杀了此怪后剩余次数比之前到达单元mapa[j-b][i+a]的剩余次数还要多) 将mapa[j-b][i+a]的剩余次数更新为mapa[j][i]-1。 否则不予更新。4.重复步骤3 k次以读取完所有怪的信息5.判断con是否大于以下为代码实现:

#include <iostream>#include <cstdio>#include <cstdlib>#include <memory.h>#include <cstring>#include <queue>#include <cmath>#include <algorithm>#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define max(a, b)  (((a) > (b)) ? (a) : (b))#define min(a, b)  (((a) < (b)) ? (a) : (b))#define N 210using namespace std;/**    注意:这里由于对所获经验上限不确定,故(N-n)需要大于单次杀怪所获的最大经验值(防止数组越界),         这里是(N-100)>100,故 N 应大于200*/int main(){    int mapa[N][N]; //mapa[i][j]代表在还剩 i 点忍耐值、获得了 j 点经验的情况下还能杀mapa[i][j]个怪    int n,m,k,s;    //n:所需经验值、m:忍耐度、k:怪的种类、s:最多杀怪数    int a,b,i,j;    //a:经验值、b:会减少的忍耐度    int con,answer; //con:用于记录当前情况下所能达到的最大经验值(用于节省时间,防止在不可能到达的经验值下浪费时间遍历)                    //answer:用于记录当前情况下,达到n点经验值所能保留的最大耐力    while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)    {        con=answer=0;  //初始化        memset(mapa[0],0,N*(m+1)*sizeof(int));        mapa[m][0]=s;        while(k-->0)        {            cin>>a>>b;  //读入第k个怪的经验值及耐力值            for(i=0;i<=con && i<=n;i++)   //i<=n:当i>n 时再搜索下去就没意义了(经验值已经满了), i<=con同理。            //完全背包思想,从0到min(con,n)遍历            {                for(j=m;j>=0;j--)   //对每一个                if(mapa[j][i]&&j-b>=0&&mapa[j-b][i+a]<=mapa[j][i]-1)  //还有次数,忍耐度有剩余,且次数比该位置之前的剩余次数还多                {                    if(i+a>con)     //更新所能获得的最大经验值                        con=i+a;                    if(i+a>=n&&answer<j-b) //经验值够了且大于之前最大值,进行替换                        answer=j-b;                    mapa[j-b][i+a]=mapa[j][i]-1;                }            }        }        if(con>=n)  //可以获得 n 点经验,输出结果            cout<<answer<<endl;        else            cout<<"-1"<<endl;    }    return 0;}


                                             
0 0
原创粉丝点击