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);
    		}
    
    
        }
    
    }
    








    

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

  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4746920.html
Copyright © 2011-2022 走看看