zoukankan      html  css  js  c++  java
  • HDU 2159 FATE (完全背包+有限尚需时日)()双费背包

    

                                                                                                                  FATE


    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
     
    **********************************************************************************************************
    解法一:全然背包
    ********************************
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<cctype>
    #define INF 0x3f3f3f3f
    #define maxn 100+10
    
    using namespace std;
    
    int cost[maxn],val[maxn],cnt[maxn];
    int dp[maxn];
    int n,m,k,s;
    
    void completepack()
    {
        memset(cnt,0,sizeof cnt);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=k;i++)
            for(int j=cost[i];j<=m;j++)
            {
                if(dp[j]<dp[j-cost[i]]+val[i])
                {
                    cnt[j]=cnt[j-cost[i]]+1;              //计数数组
                    dp[j]=dp[j-cost[i]]+val[i];
                }
            }
    }
    
    int main()
    {
        while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
        {
            int ok=1;
            for(int i=1;i<=k;i++)
                scanf("%d%d",val+i,cost+i);
            completepack();
            for(int i=0;i<=m;i++)                    //这里貌似是题目的bug,经验能够为0.
            {
                if(dp[i]>=n&&cnt[i]<=s)
                {
                    printf("%d
    ",m-i);
                    ok=0;
                    break;
                }
    
            }
            if(ok)
               printf("-1
    ");
        }
    
        return 0;
    }
    
    
    **********************************************************************************************************
    解法一:二重费用背包
    ********************************


    代码兴许-----------

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100+10
    using namespace std;
    
    int cost[maxn],val[maxn],num[maxn],dp[maxn][maxn];
    int n,m,k,s;
    
    void twocost()
    {
        memset(dp,0,sizeof dp);
        for(int i=1;i<=k;i++)
             for(int t=1;t<=s;t++)
                for(int j=cost[i];j<=m;j++)
                {
                   dp[j][t]=max(dp[j][t],dp[j-cost[i]][t-1]+val[i]);
                }
    }
    
    int main()
    {
        int minn;
        while(scanf("%d%d%d%d",&n,&m,&k,&s) != EOF)
        {
            for(int i = 1; i <= k; i++)
    			scanf("%d%d",&val[i],&cost[i]);
            twocost();
    
            if(dp[m][s] < n)
    			printf("-1
    ");
    		else
    		{
    			minn = m;
    			for(int i = 0; i <= s; i++)
    			{
    				for(int j = 0; j <=m; j++)
    					if(dp[j][i] >= n&&j < minn)
    						minn = j;
    			}
    			printf("%d
    ",m - minn);
    		}
    
    
        }
    
    }
    








    

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    循环移位算法
    关于Java中2.0-1.1!=0.9的问题
    Java基础语法(三)
    Java基础语法(二)
    Java基础语法(一)
    关于Java运行机制
    Java从零开始(前篇)
    关于.ssh目录下的known_hosts文件的补充
    解决 bash cd too many arguments 报错
    Markdown学习笔记(一)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4746920.html
Copyright © 2011-2022 走看看