B 维背包+完全背包 Hdu2159

<span style="color:#3333ff;">/*
 ————————————————————————————————————————————————————————————————————————————————————————————————
    author   :     Grant Yuan
    time     :     2014.7.19
    aldorithm:     二维背包+全然背包

————————————————————————————————————————————————————————————————————————————————————————————————
B - 二维费用背包 基础
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit

Status
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<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 9999999;
using namespace std;

int dp[2][105][105];
int exp,exd,num,kid;
//exp:经验 ;exd: 忍耐度; num:怪的个数; kid:怪的种类;
//dp[前i种怪][已经杀了j个怪][消耗k的忍耐度]=所获得经验的最大值
int b[105],a[105];

int main()
{
	while(~scanf("%d%d%d%d",&exp,&exd,&kid,&num)){

	  for(int i=0;i<kid;i++)
		  scanf("%d%d",&a[i],&b[i]);
		memset(dp,0,sizeof(dp));

	   for(int i=0;i<kid;i++)//种类
		for(int j=1;j<=num;j++)//杀怪的个数
		  for(int k=0;k<=exd;k++)//消耗的忍耐度
		  {
			if(k>=b[i])
		         dp[(i+1)&1][j][k]=max(dp[(i+1)&1][j-1][k-b[i]]+a[i],dp[i&1][j][k]);
		    else
		         dp[(i+1)&1][j][k]=dp[i&1][j][k];
		        }

		int m=INF;
	   if(dp[kid&1][num][exd]<exp)
		  printf("-1\n");
	   else {//寻找最小的忍耐度
				  for(int k=0;k<=exd;k++)
				    if(dp[kid&1][num][k]>=exp&&k<m)
				      m=k;
		    cout<<exd-m<<endl;
	   }
	}
	return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 9999999;
using namespace std;

int dp[105][105];
int exp,exd,num,kid;
//exp:经验 ;exd: 忍耐度; num:怪的个数; kid:怪的种类;
//dp[前i种怪][已经杀了j个怪][消耗k的忍耐度]=所获得经验的最大值
int b[105],a[105];

int main()
{
	while(~scanf("%d%d%d%d",&exp,&exd,&kid,&num)){

	  for(int i=0;i<kid;i++)
		  scanf("%d%d",&a[i],&b[i]);
		memset(dp,0,sizeof(dp));

	   for(int i=0;i<kid;i++)//种类
		for(int j=1;j<=num;j++)//杀怪的个数
		  for(int k=exd;k>=b[i];k--)//消耗的忍耐度
		  {
		         dp[j][k]=max(dp[j-1][k-b[i]]+a[i],dp[j][k]);
		        }
	     int m=INF;
	   if(dp[num][exd]<exp)
		  printf("-1\n");

	   else {//寻找最小的忍耐度
				  for(int k=0;k<=exd;k++)
				    if(dp[num][k]>=exp&&k<m)
				      m=k;
		    cout<<exd-m<<endl;
	   }
	}
	return 0;
}
</span>

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

时间: 2024-12-06 18:50:01

B 维背包+完全背包 Hdu2159的相关文章

B 二维背包+完全背包 Hdu2159

<span style="color:#3333ff;">/* ------------------------------------------------------------------------------------------------ author : Grant Yuan time : 2014.7.19 aldorithm: 二维背包+完全背包 ----------------------------------------------------

HDU 3591 The trouble of Xiaoqian(多重背包+01背包)

HDU 3591 The trouble of Xiaoqian(多重背包+01背包) http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意: 有一个具有n种货币的货币系统, 每种货币的面值为val[i]. 现在小杰手上拿着num[1],num[2],-num[n]个第1种,第2种-第n种货币去买价值为T(T<=20000)的商品, 他给售货员总价值>=T的货币,然后售货员(可能,如果小杰给的钱>T, 那肯定找钱)找钱给他. 售货员每次总是用

01背包&amp;完全背包

·01背包&完全背包基础 01背包模型:给定n个物品,第i个物品体积为Wi,价值为Vi,背包容量为sum,选择一些物品放入背包,要求总价值最大. F[i,j]表示前i个物品放入容量为j的包里获得的最大价值. 对于任意一个物品都有两种状态,要么放要么不放,不放的话很显然价值同前,放的话就要从包里拿出一部分体积. 完全背包模型:给定n种物品,第i个物品体积为Wi,价值为Vi,背包容量为sum,选择一些物品放入背包,要求总价值最大. F[i,j]表示前i种物品放入容量为j的包里获得的最大价值. 01背

HDU1864_最大报销额(背包/01背包)

解题报告 题目传送门 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define inf 99999999 using namespace std; int v,w[35],d[4],dw1,sum,dp[31*1000*100]; int main() { double Q,dw; int n,i,j,m,t; char c; while(~sc

HDU1114_Piggy-Bank(背包/完全背包)

解题报告 题目传送门 题意: 给金币的面额和重量,求装满储蓄罐的最小价值. 思路: 完全背包基础,初始dp为最大,dp[0]=0表示储蓄罐为空价值为0; 状态转移方程就是dp[j]=min(dp[j],dp[j-w[i]]+c[i]) #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i

HDU2602_Bone Collector(背包/01背包)

解题报告 题目传送门 题意: 容量为v的大小,物品数n,每个物品有价值和容量,求能装进包的最大价值. 思路: 基础01背包. dp[j]=max(dp[j],dp[j-c[i]]+w[i]) #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,v,w[1010],c[1010]

POJ 3260 多重背包+完全背包

前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的WiFi,不试不知道,一试吓一跳,用个手机软件简简单单就连上了,然后在浏览器输入192.168.1.1就能看到他的路由器的一切信息,包括密码,然后打开笔记本……好了,废话不多说,能连上网后第一时间当然是继续和队友之前约好的训练了. 今天翻看到之前落下的一道混合背包题目,然后在草稿本上慢慢地写递推方程,把一些细节细心地写好…(本来不用太费时间的,可是在家嘛,一会儿妈走来要我教她玩手机,一会儿有一个亲戚朋

HDU1248_寒冰王座(背包/完全背包)

解题报告 题目传送门 无聊的水题. #include <iostream> #include <cstring> #include <cstdio> #define inf 0x3f3f3f3f using namespace std; int c[10100],w[10100],dp[11000],v,n; int main() { int t,i,j; scanf("%d",&t); while(t--) { memset(dp,0,si

HDU2191_悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(背包/多重背包)

解题报告 题目传送门 题意: 中文不多说; 思路: 基础多重背包,每个物品有多个可以选,转换成01背包解. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,m,v,p,h,cc,w[1010],c[1010],dp[1010]; scanf("%d",&